« 自分のブログをベクトルにして分布をみた(4) | トップページ | dynabook T451/35DWのHDDをSSDに換装してメモリ4GBを8GBに増量しました »

2020.08.30

macOS & Dockerで動作するリアルタイム画像認識デモ環境を作ってみた(1)

(2023.03.04追記)
VirtualBox + boot2docker改を使用する本記事とは異なる方法を別記事に記載しました。
(2023.03.04追記ここまで)

夏休みの宿題(?)として、リアルタイム画像認識を行うでも環境をDocker使って、しかもこれらをmacOS上で動かす、ということを試してみましたのでその過程をメモ。画像認識ツールとしてYOLO v3を使用します。Webカメラ(webcam)で撮影した動画をリアルタイムに画像認識して結果を表示するという、まあ、よくあるデモを実現します。
今回はYOLO v3のPyTorch実装のデモを実行してみます。

MacでDockerを使うのは、Macと画像認識環境を分離したいという動機から。しかし、Docker for MacではUSB機器を扱えないために、Dockerのドライバを別に用意する必要があります。そこでVirtualBox上で動作し、かつUSB機器を認識できるDockerマシンを起動するためのboot2docker.isoを用意します。さらにYOLO v3を動作させるためのDocker containerを用意します。

実行環境は以下のとおり。
マシン:Mac mini (2018) Intel Core i7 (物理コア数6+メモリ16GB)
OS:macOS Catalina
仮想化製品:VirtualBox 6.1.12

この環境構築には大まかに2段階の手順を踏みます。

1段階目はUSB webcamを使うことができるboot2dockerイメージの構築です。これは次のサイトに基づいています。
Connect the webcam to Docker on Mac or Windows by Jongmin Park: Medium

2段階目はYOLO v3のDockerイメージ作成です。Webに複数掲載されている構成を採用し、主に次のサイトを参照しました。
CPU環境でYOLOv3をpythonで動かしてリアルタイム画像認識してみた: Qiita
他にも多くのサイトを参考にしていますがすべて掲載しきれないので割愛。皆様、ありがとうございます。

1.boot2docker.isoを改変
USBを認識できるDocker Machineを用意するため、Boot2Docker Enable to use Webcam for macの手順にしたがって、boot2docker.isoを生成します。このDockerイメージはc7e5c3時点のboot2dockerイメージのDockerfileとkernel_configに手を入れてmedia関係のドライバmoduleを有効にし、Docker for Macを使ってDockerイメージをビルドしました。


$ git clone https://github.com/boot2docker/boot2docker
$ cd boot2docker
$ git reset --hard c7e5c3

このコマンドを実行することにより、sourceをコミットされた状態をc7e5c3時点まで戻し、Dockerfile及びkernel_configに対して上述した変更を行います。次いでDockerイメージをビルドします。


$ docker build -t boot2docker .
$ docker run --rm boot2docker > boot2docker.iso

ちなみに最近のboot2dokerはカーネルイメージ生成方法が随分変更されているので、最新イメージに基づく方法を試しはしたものの成功に至っていません。

2.VirtualBox + boot2docker.iso仮想マシンを起動
VirtualBoxをDocker Machineのドライバとして使用するため、isoイメージを~/work/boot2docker.isoとして配置し、次のコマンドを実行して仮想マシン名をwebcam2とします。仮想マシンを作成したら当該仮想マシンを停止します。CPUコア数、メモリ、ディスク容量を適宜調整して下さい。


$ docker-machine create --driver virtualbox \
--virtualbox-cpu-count=6 \
--virtualbox-memory=4096 \
--virtualbox-disk-size=100000 \
--virtualbox-boot2docker-url ~/work/boot2docker.iso \
webcam2
$ docker-machine stop webcam2

仮想マシンを適宜行います。次のようにコマンドでも設定できますが、テスト環境程度であればGUIを使った方が手軽と思います。
ここではUSB 3.0の設定になっていますが、ご自分の環境に合わせて下さい。


$ vboxmanage modifyvm webcam2 --usb on
$ vboxmanage modifyvm webcam2 --usbxhci on
$ vboxmanage usbfilter add 0 --target webcam2 --name 'AllDevices'
$ docker-machine start webcam2

3.Dockerイメージをビルド
いよいよDockerイメージをビルドします。openCV + PyTorch + Torchvisionの環境をビルドします。
起動したDockerコンテナに対し、sshでログインしてDockerコンテナ環境を使用する想定です。Dockefileと同じ場所にAnacondaのインストールスクリプトをAnaconda installer archiveからDownloadしたここではAnaconda3-2020.07-Linux-x86_64.shを置いてビルドします。


FROM debian:10.5-slim
MAINTAINER tonop

RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:hoge' | chpasswd
RUN echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config
RUN echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config
RUN echo 'Port 22' >> /etc/ssh/sshd_config
RUN echo 'Protocol 2' >> /etc/ssh/sshd_config
RUN echo 'X11Forwarding yes' >> /etc/ssh/sshd_config
RUN echo 'X11UseLocalhost no' >> /etc/ssh/sshd_config
RUN echo 'export LC_ALL=C' >> /root/.bashrc

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

# For installing applications
RUN apt-get install -y \
x11-apps \
usbutils \
v4l-utils \
fswebcam \
eog \
less \
vim \
wget && \
rm -rf /var/lib/apt/lists/*

# Install Anaconda
COPY Anaconda3-2020.07-Linux-x86_64.sh /opt/
RUN bash /opt/Anaconda3-2020.07-Linux-x86_64.sh -b -p /opt/anaconda3 && \
rm /opt/Anaconda3-2020.07-Linux-x86_64.sh
RUN echo "PATH=/opt/anaconda3/bin:$PATH" >> ~/.bashrc
RUN echo "source activate yolo3" >> ~/.bashrc

# Install tools by conda
RUN /opt/anaconda3/bin/conda update -n base -c defaults conda -y
RUN /opt/anaconda3/bin/conda create -n yolo3 python=3.7
RUN /opt/anaconda3/bin/conda install -n yolo3 -c defaults matplotlib pandas
RUN /opt/anaconda3/bin/conda install -n yolo3 -c conda-forge opencv=4.4.0
RUN /opt/anaconda3/bin/conda install -n yolo3 -c pytorch pytorch torchvision

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

6行目はrootのパスワード設定ですので、適宜変更して下さい。
そして、Dockerイメージをビルドします。


$ eval $(docker-machine env webcam2)
$ docker build -t yolo3:0.2 .
$ docker images

eval $(docker-machine env webcam2)はVirtualBoxをドライバとしてdocker-machineコマンドを使用するための環境変数を設定するコマンドです。Anaccondaを利用することにより結構サイズが大きくなる上、openCV、PyTorch、TorchvisionをインストールしたのでDockerイメージのサイズは11.9GBと随分大きくなりました。

4.Webcamの認識を確認
DockerエンジンにログインしてUSB機器接続状態を確認します。


$ eval $(docker-machine env webcam2)
$ docker-machine ssh webcam2
$ udevadm monitor

2020083001
デバイスのマウントをオン/オフを繰り返すと上のターミナルの表示が変わりますのでご確認下さい。

5.Dockerコンテナを起動
Dockerコンテナを起動してYOLO v3を使ってリアルタイム画像認識デモを実行します。macOSに接続されたWebcamをVirtualBoxで動作するDockerマシンが認識し、この認識されたデバイスをDockerコンテナに接続します。
macOSのX Window、Dockerマシン、Dockerコンテナを起動するスクリプトを次に示します。


#!/bin/bash
open -a XQuartz
socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"DISPLAY\" &
IP=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')
docker-machine start webcam2
eval $(docker-machine env webcam2)
echo "docker run"
docker run --rm -p 22000:22 -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$IP:0 --device /dev/video0 -v ~/work:/root/work yolo3:0.2

6.Dockerコンテナにログインしてデモプログラムを実行
Dockerコンテナにsshログインして操作します。まず、docker-machineにsshログインしてDockerコンテナに割り振られたIPアドレスを確認します。


$ docker-machine ssh webcam2
$ ifconfig | grep inet

inet:XXX.XXX.XXX.XXXを確認してDockerコンテナにログインします。


$ ssh -X -p 22000 root@XXX.XXX.XXX.XXX

次のようなdemo.pyを作成してpython3 demo.py実行します。cv2.VideoCapture()の引数はWebカメラの順番で決まります(/dev/video0, /dev/video1などの順番に対応)。


import cv2

capture = cv2.VideoCapture(0)

while(True):
ret, frame = capture.read()
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break

capture.release()
cv2.destroyAllWindows()

2020083002

上のようにWebcamの動画を確認します。'q'を入力すると終了します。
最後にいよいよYOLO v3のデモを実行します。workディレクトリ配下にYOLO v3のPyTorch実装とweightファイルをDownloadします。


$ git clone https://github.com/ayooshkathuria/pytorch-yolo-v3
$ cd pytorch-yolo-v3
$ wget https://pjreddie.com/media/files/yolov3.weights
$ python3 cam_demo.py

2020083003
GPU不使用の条件における実行ですが、7-10FPS程度で画像認識しました。

|

« 自分のブログをベクトルにして分布をみた(4) | トップページ | dynabook T451/35DWのHDDをSSDに換装してメモリ4GBを8GBに増量しました »

パソコン・インターネット」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




« 自分のブログをベクトルにして分布をみた(4) | トップページ | dynabook T451/35DWのHDDをSSDに換装してメモリ4GBを8GBに増量しました »