search
LoginSignup
10

More than 1 year has passed since last update.

posted at

updated at

dockerでウェブカメラの映像を表示する

ウェブカメラから映像を取得しPC画面上に表示するというプログラムをdockerから行えるようにした際のメモです。
(物体検知を用いた検討を行うための環境ですが、本メモでは物体検知は行っていません。)

行ったこと

  1. Dockerfileを使ってpullしたimageをカスタマイズ
  2. ウェブカメラの映像を表示でする。
  3. Jupyter notebookをみられるようにする。(追加)

ホストの環境

OS
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.6 LTS"

dockerの環境

こちらで構築した環境を使っています。

1. Dockerfileを使ってpullしたimageをカスタマイズ

nvidia-dockerからDeepLearningのフレームワークとしてpytorchのimageをpullします。そのdocker imageをベースに、open-cvなど映像を扱うために必要なモジュールのインストールを行います。

$ docker pull nvcr.io/nvidia/pytorch:20.03-py3
  // imageのpullに小一時間程度かかります

$ docker images
REPOSITORY                    TAG                       IMAGE ID            CREATED            SIZE
nvcr.io/nvidia/pytorch     20.03-py3                  16c4987611fa        5 weeks ago         9.39GB

open-cvのインストールには、libsm6 libxext6 libxrender-devが必要だったため、Dockerfileではそれらのインストールも行います。
次に、opencvの出力を画面に表示できるようにします。~/.bashrcに QT_X11_NO_MITSHM=1 を追記する必要があるので、そちらもDockerfile以下のように記載しました。

Dockerfile
FROM nvcr.io/nvidia/pytorch:20.03-py3

ARG DEBIAN_FRONTEND=noninteractive

RUN apt-get update && \
    apt-get install -y python3-tk && \
    pip install --upgrade pip && \
    apt-get install -y libsm6 libxext6 libxrender-dev && \
    pip install opencv-python && \
    pip install pytest && \
    pip install nose

RUN echo 'export QT_X11_NO_MITSHM=1' >> ~/.bashrc && \
    source ~/.bashrc

上記Dockerfileを用いて、docker imageを作成します。

$cd **/work/  [Dockerfileのあるフォルダ]
$docker build -t [repository名]:[tag名] . 
例)$docker build -t test:1 . 

2. ウェブカメラの映像を表示でする。

次に、PCに接続したウェブカメラの映像を取得できるようにします。
USBカメラをPCにつないで、ホスト側でデバイスの確認を行います。

$sudo apt install v4l-utils
$v4l2-ctl --list-device

UVC Camera :
    /dev/video0

と表示され、/dev/video0で指定できることがわかります。
そこで、以下のようにデバイスを指定してdockerをrunします。

$xhost +
$docker run --gpus all -it --rm \
           --device /dev/video0:/dev/video0:mwr \
           -v /tmp/.X11-unix:/tmp/.X11-unix \
           -e DISPLAY=$DISPLAY test:1

=============
== PyTorch ==
=============

NVIDIA Release 20.03 (build 11122848)
PyTorch Version 1.5.0a0+8f84ded

Container image Copyright (c) 2019, NVIDIA CORPORATION.  All rights reserved.
(省略)....

Dockerfileで設定した内容が反映されているかを確認します。

#cat ~/.bashrc
.....
export QT_X11_NO_MITSHM=1
#python
>>>import cv2
>>>print(cv2.getBuildInformation())

.....
  Video I/O:
    DC1394:                      NO
    FFMPEG:                      YES
      avcodec:                   YES (ver 58.19.100)
      avformat:                  YES (ver 58.13.100)
      avutil:                    YES (ver 56.18.100)
      swscale:                   YES (ver 5.2.100)
      avresample:                NO
    GStreamer:                   NO
    libv4l/libv4l2:              NO
    v4l/v4l2:                    linux/videodev.h linux/videodev2.h
    gPhoto2:                     NO
.....

以下のようなコードを実行するとUSBカメラから取得した映像が表示できます。

test.py
import cv2
camera_width = 1280
camera_height = 960
vidfps = 30

cam = cv2.VideoCapture(0)
cam.set(cv2.CAP_PROP_FPS, vidfps)
cam.set(cv2.CAP_PROP_FRAME_WIDTH, camera_width)
cam.set(cv2.CAP_PROP_FRAME_HEIGHT, camera_height)
cv2.namedWindow("USB Camera", cv2.WINDOW_AUTOSIZE)

while True:
    ret, color_image = cam.read()
    if not ret:
        continue
    cv2.imshow('USB Camera', color_image)
    if cv2.waitKey(1)&0xFF == ord('q'):
        break

3. jupyter notebookを見られるようにする.

提供されるコードがjyupyter notebookになってきたので、こちらも見られるようにしました。
今回はベースとしているpytorchのdocker(nvcr.io/nvidia/pytorch 20.03-py3)にjupyter notebookが
インストールされていたので、Dockerfileは同じままでOKでしたが、入っていない場合には、
Dockerfileに追記します。

Dockerfile
FROM nvcr.io/nvidia/pytorch:20.03-py3

ARG DEBIAN_FRONTEND=noninteractive

RUN apt-get update && \
    apt-get install -y python3-tk && \
    pip install --upgrade pip && \
    apt-get install -y libsm6 libxext6 libxrender-dev && \
    pip install opencv-python && \
    pip install jupyter && \
    pip install pytest && \
    pip install nose

RUN echo 'export QT_X11_NO_MITSHM=1' >> ~/.bashrc && \
    source ~/.bashrc

そうしてイメージを作成したのち、dockerのcontainerを立ち上げます。

$xhost +
$docker run --gpus all -it --rm \
           --device /dev/video0:/dev/video0:mwr \
           -p 10000:8888 \
           -v /[working directory path]/:/work \
           -v /tmp/.X11-unix:/tmp/.X11-unix \
           -e DISPLAY=$DISPLAY test:1

コンテナが起動したら、jupyter notebookを立ち上げます。

$cd /work
$jupyter notebook &

    To access the notebook, open this file in a browser:
        file:///root/.local/share/jupyter/runtime/nbserver-346-open.html
    Or copy and paste one of these URLs:
        http://hostname:8888/?token=b4fd4738d4173fc924b86107cba9330d24419df8cd818c0b

ホスト側でブラウザを立ち上げ, URLとして http://localhost:10000 を入力します。
tokenを聞く画面が表示されたら、上記のtoken=以下の文字列をコピーして入力すると、ブラウザ上に、
/work以下のフォルダが表示されます。

参考文献
1. dockerからopencvの画像を表示する。
2. dockerでデバイスカメラを共有する。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
10