Dockerコンテナ上でOpenCVを実行する環境を構築し、
OpenCVの公式サンプルを実行しました。
その手順とハマったことを中心に整理しました。
コンテナ上でGUIプログラムを
実行する手順もまとめています。
今回作成したDocke Image
https://hub.docker.com/r/rimacdocker/opencv_demo
やったこと
以下の手順で
Docker上でOpenCVの公式サンプルを実行しました。
==> 実行結果
ホストPC側の環境
MacOS 10.13.1
Docker 18.09.2
1. Dockerコンテナ上でOpenCVが動く環境の構築
詳細な手順は以下の通り
1-1. OSイメージの取得、コンテナの起動
1-2. コンテナ内での必要なパッケージ、ライブラリのインストール
1-3. コンテナへのOpenCVリポジトリのコピー
1-1. OSイメージの取得、コンテナの起動
コンテナを起動して環境を構築していきます。
今回はUbuntuの最新イメージを取得して、コンテナを起動します。
$ docker run -it ubuntu
1-2. 必要なパッケージ、ライブラリのインストール
OpenCV公式sampleを実行するのに必要なパッケージ、ライブラリをインストールします。
sampleを実行するだけなら、それほど複雑な環境は要求されません。
インストールしたパッケージ
-
Ubunutuパッケージ
- python3
- python3-pip
- python3-tk
- libsm6
- libxext6
- libxrender-dev
-
Pyhtonライブラリ
- opencv-python
- numpy
- matplotlib
コンテナ内で実行したコマンド
# パッケージマネージャの最新化
$ apt update
$ apt upgrade
# Python, Pipのインストール
$ apt install python3
$ apt install python3-pip --fix-missing
# opencvのインストール
$ pip3 install opencv-python
# opencv内部で使っているのでインストール
$ pip3 install numpy
# opencvの実行に必要なUbuntuパッケージをインストール
$ apt install -y libsm6
$ apt install -y libxext6 libxrender-dev —fix-missing
# OpenCV公式のsampleの実行に必要なのでインストール
$ apt install python3-tk
$ pip3 install matplotlib
1-3. コンテナへのOpenCVリポジトリのコピー
ctrl + p + q
で一度、コンテナを停止させずに抜けます。
以降の作業はホストPC側で行ってください。
ホストPCでOpenCVのリポジトリをクローンします。
$ git clone https://github.com/opencv/opencv.git
その後、起動しているコンテナIDを調べます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
123456789ABC opencv_demo "/bin/bash" 2 minutes ago Up 2 minutes hoge_hoge
調べたコンテナID(上の例では'123456789ABC')で指定して
ホストPCからコンテナへ
OpenCVリポジトリをコピーします。
この時に、
ホスト側のopencvローカルリポジトリがある場所は相対パスで、
Dockerコンテナ側の配置パスは絶対パスで書きます。
docker cp ./opencv/ 123456789ABC:/root/
これで作成するコンテナとしては完成です。
docker commitでここまでの状態を
イメージとして保存しておくと良いです。
docker commit 123456789ABC opencv_demo
2. コンテナの画面出力をホストPCのディスプレイに設定
OpenCVの公式サンプルは実行結果を画面に出力しますが、
コンテナプロセスには紐付くディスプレイがないので
コンテナの画面出力をホストPCのディスプレイに飛ばす必要があります。
そのための設定を行っていきます。
この作業はホストPCで実施する作業です。
詳細な手順は以下の通り。
2-1. Mac用X11インストール
2-2. ホストPCのディスプレイを外からアクセス可能にする
2-3. コンテナへのOpenCVリポジトリのコピー
2-1. Mac用X11インストール
2016年以降MacにはX11が入ってないので
X11をインストールする必要があります。
使用するPCにX11が入っていればこの手順は不要です。
$ brew cask install xquartz
尚、brew install
では入らないので
brewを拡張したcaskを使ってインストールしました。
インストール後にマシンを再起動します。
2-2. ホストPCのディスプレイを外からアクセス可能にする
xhost コマンドでホストPC以外からも
ホストPCのディスプレイへアクセス可能にします。
$ xhost +
2-3. コンテナからのアクセスを待ち受ける
socatコマンドを使って、
ホストPCのディスプレイへのアクセスを待ち受けます。
# socatのインストール
$ brew install socat
# socat実行
$ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
socatコマンド実行後、
標準出力が帰ってこない状態で待ち受けるので
以降の作業は別ターミナルを立ち上げて行います。
注意点: xhost -
xhost +
でディスプレイへの外からのアクセスを全て可能にするのは
セキュリティ的には望ましくないので
sampleプログラムの実行が終わったら
$ xhost -
でセキュリティレベルを元に戻しておいた方が良いです。
3. コンテナでサンプルプログラムの実行
手順1で作成したコンテナイメージをdocker runします。
この時にホストPCのX11の認証情報を
コンテナのボリュームにマウントします。
$ docker run -it -e DISPLAY=XXX.XXX.XXX.XXX:0 \
-v /Users/r_i/.Xauthority/:/root/.Xauthority \
-v /tmp/.X11-unix/:/tmp/.X11-unix opencv_demo /bin/bash
※ XXX.XXX.XXX.XXX
の部分はホストPCのIPアドレスに読み替えて下さい。
これによりコンテナの画面出力を
ホストPCのウィンドウに表示可能にしてコンテナを起動します。
起動したコンテナで以下のコマンドで、
OpenCVのサンプルプログラムを実行します。
python3 /root/opencv/samples/python/demo.py
実行結果
まとめ
docker上でOpenCVを実行することで
ホストPC環境に手を入れることなく、
OpenCVのデモアプリを実行出来ました。
docker上で実行したプログラムの画面出力を
ホストPCのディスプレイに表示させると
コンテナの可能性が広がるんじゃないでしょうか。