LoginSignup
14

More than 3 years have passed since last update.

Docker x 可視化がうまくいかずハマったのでまとめてみた!

Last updated at Posted at 2020-01-19

はじめに

Docker上でOpenCV等のビジョン系ライブラリを使用する時は、DockerコンテナとローカルPCのディスプレイを接続する必要がありますが、この方法が分からず結構な時間を要してしまいましたので、途中で遭遇したトラブルとその解決策を含めてまとめていきたいと思います!

開発環境

Ubuntuです!詳細は下記コマンドでチェックしておきます!

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.3 LTS"

$ arch
x86_64

Dockerイメージのダウンロード

まずはDocker HubからDockerイメージをダウンロードします。Docker Hubで公開されているDockerイメージは、自由にダウンロード、保存することができます。

$ docker pull ubuntu:18.04

Dockerコンテナのデプロイ

保存済みのDockerイメージを用いて、Dockerコンテナを立ち上げます。Dockerコンテナをデプロイする際、様々なオプションがあります[1][2]
今回使用するオプションは、-it--privileged--env--volume--nameです。
まず-itにより、Dockerコンテナに対して擬似端末(pseudo terminal)を割り当てることで、Dockerコンテナ上でBashを使用できるようにします。
続いて--privilegedにより、全てのデバイスに対するアクセスを許可します。
--envでは、Dockerコンテナ内で使用する環境変数を指定します。
--volumeでは、ホストOSのディレクトリをゲストOSにマウントすることができます[3]
--nameではコンテナ名を指定することができます。

$ docker run -it \
             --privileged \
             --env="DISPLAY=$DISPLAY" \
             --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
             --volume="$HOME/ws/:/home/" \
             --name="ubuntu_cv2" \
             ubuntu:18.04

パッケージのインストール

まずはUbuntuお決まりのアップデート、アップグレードです。

# apt-get update
# apt-get upgrade

続いて、エディタとしてVimをインストールしておきます。

# apt-get install vim

プログラミング言語にはPythonを使用します。

# apt-get install python3.6 \
                  python3-dev \
                  python3-pip \
                  libffi-dev \
                  libssl-dev

pipを使用してOpenCVをインストールします。

# pip3 install opencv-python

画像表示プログラムを作成

OpenCVを使用して画像を表示する基本的なプログラムを作成しておきます。

open_image.py
import cv2

# Load an color image
img = cv2.imread('test.jpg')

# Show the image
cv2.imshow('image',img)

# Stop when 0 pressed
cv2.waitKey(0)
cv2.destroyAllWindows()

トラブル1:OpenCVを正しくインポートできない

まずPythonを実行して、OpenCVが正しくインポートできるかテストしてみます。

# python3
>>> import cv2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/dist-packages/cv2/__init__.py", line 3, in <module>
    from .cv2 import *
ImportError: libSM.so.6: cannot open shared object file: No such file or directory

案の定、エラーによりOpenCVをインポートできません。このエラーは、libsm6libxext6libxrender-devのインストール[4]により解決できます。

# apt-get install -y libsm6 libxext6 libxrender-dev

インストール後、もう一度OpenCVをインポートできるかテストしてみます。

# python3
>>> import cv2

OKですね!

トラブル2:画像を表示できない

先程作成したopen_image.pyを実行してみましょう。

# python3 open_image.py
No protocol specified
: cannot connect to X server :1

PCとのディスプレイ接続に失敗しているようです。ホストPC側で、ゲストPCからのホストPCディスプレイへの接続要求を拒否していることが理由でした。別のターミナルを開けて、ホストPC側で下記コマンドを実行すると、ディスプレイへの接続を許可[5][6][7]することができます。

$ xhost +
access control disabled, clients can connect from any host

再度Dockerコンテナを実行していたターミナルに戻り、open_image.pyを実行してみましょう。

# python3 open_image.py
X Error: BadAccess (attempt to access private resource denied) 10
  Extension:    130 (MIT-SHM)
  Minor opcode: 1 (X_ShmAttach)
  Resource id:  0x247
...

別のエラーが出てきました。エラー原因を調査したところ、環境変数にQT_X11_NO_MITSHM=1を追加することで解決できるそうです。まずは.bashrcファイルをVimで開きます。

# vim ~/.bashrc

続いて、環境変数QT_X11_NO_MITSHM=1を追記します。

export QT_X11_NO_MITSHM=1

.bashrcファイルを保存した後、環境変数の追加を反映させるため、sourceコマンド[8]を実行します。

# source ~/.bashrc

echoコマンドを使用して、環境変数が正しく追加されているか確認してみましょう。

# echo $QT_X11_NO_MITSHM
1

OKですね!三度目の正直です。open_image.pyを実行してみましょう!

# python3 open_image.py

画像が表示されました!!!

おわりに

様々なトラブルがありましたが、無事にDockerコンテナとPCディスプレイを接続して、OpenCVにより画像を表示させることができました。今回の検証より、Dockerコンテナをデプロイする際には、下記のように環境変数QT_X11_NO_MITSHM=1を追加しておくと良いことも分かりました。

$ docker run -it \
             --privileged \
             --env="DISPLAY=$DISPLAY" \
             --env="QT_X11_NO_MITSHM=1" \
             --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
             --volume="$HOME/ws/:/home/" \
             --name="ubuntu_cv2" \
             ubuntu:18.04

これからDockerマスターを目指して頑張っていこうと思います!
読んで頂いた方々、ありがとうございます!!!

参考文献

[1] Docker run options, https://docs.docker.com/v17.12/edge/engine/reference/commandline/run/
[2] Example of docker run, https://qiita.com/tnarihi/items/275c009e9dec1306893f
[3] How to mount on docker, https://docs.docker.com/v17.09/engine/admin/volumes/bind-mounts/
[4] How to solve opencv import error, https://github.com/NVIDIA/nvidia-docker/issues/864
[5] Open X server, https://unix.stackexchange.com/questions/121716/unable-to-open-x-server
[6] Allowing computers access, https://www.stitson.com/pub/book_html/node72.html
[7] About xhost, https://wiki.archlinux.jp/index.php/Xhost
[8] Source command, https://bash.cyberciti.biz/guide/Source_command

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
  3. You can use dark theme
What you can do with signing up
14