Help us understand the problem. What is going on with this article?

Docker上でOpenCVの公式sampleを実行してみた

More than 1 year has passed since last update.

Dockerコンテナ上でOpenCVを実行する環境を構築し、
OpenCVの公式サンプルを実行しました。

その手順とハマったことを中心に整理しました。

コンテナ上でGUIプログラムを
実行する手順もまとめています。

今回作成したDocke Image
https://hub.docker.com/r/rimacdocker/opencv_demo

やったこと

以下の手順で
Docker上でOpenCVの公式サンプルを実行しました。

  1. Dockerコンテナ上でOpenCVが動く環境の構築
  2. コンテナの画面出力をホストPCのディスプレイに設定
  3. コンテナ上でサンプルプログラムの実行

==> 実行結果

ホスト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

実行結果

コマンド実行後、以下の画面が立ち上がって
image.png

以下のようにGUIで、選択したプログラムを実行できる
image.png

まとめ

docker上でOpenCVを実行することで
ホストPC環境に手を入れることなく、
OpenCVのデモアプリを実行出来ました。

docker上で実行したプログラムの画面出力を
ホストPCのディスプレイに表示させると
コンテナの可能性が広がるんじゃないでしょうか。

Taro_man
▷ Djangoが好きです。 ▷ Pythonはもっと好きです。 ▷ Webサービスを運営してます。 ▷ https://siru-trend.com/ ▷ お仕事依頼はこちらまで ▷ taro.man.qiita@gmail.com
https://siru-trend.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away