#はじめに
筆者はQiita初投稿である。
Qiitaの書き方について「もっとこうした方がいいよ!」などコメント頂けると幸いである。
#経緯と問題
###経緯
機械学習の勉強として、かめ@米国データサイエンティストさんの記事を参考にし、Dockerコンテナ上(Ubuntu)でJupyter Labを使用できるようにした(参照1)。また、追加でOpenCVをインストール&インポートを行った(参照2)。
(参照1)DockerでJupyter Labを使う
(参照2)OpenCVによる画像の読み込みと色空間の変換,表示
###問題
OpenCVをいろいろ勉強しようと思い、参照1・参照2で構築したUbuntu上のJupyter LabでOpenCVのimshowで画像を表示しようとするとKernel Restartingとなり表示されない。
その際にTerminal上で表示されたJupyter Labのログ?は以下の通りある。
cannot connect to X server ? なんじゃそりゃ?
[I 12:38:37.627 LabApp] Kernel started: a79b264a-3b96-463d-83d6-64904b98938a
: cannot connect to X server
[I 12:38:46.627 LabApp] KernelRestarter: restarting kernel (1/5), keep random ports
kernel a79b264a-3b96-463d-83d6-64904b98938a restarted
また、そのとき実行したコードはこちらである。
import cv2
import os
img = cv2.imread("src/Berry.jpg")
cv2.imshow("img",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
#対処法
###XQuartzの導入・起動
cannot connect to X serverについて調べてみると、
UNIX系のOSではGUI環境(画像を表示する)を作るのにX Window Systemを利用する必要があるらしい。
XquartzはmacOS用のX Window Systemでそれを導入・起動する。
$ brew cask install xquartz #インストール
$ open -a XQuartz #起動
ちなみにX Window Systemはクライアントサーバ型のシステムで、今回は以下の通りである。
・Xクライアント:macOS上のDockerコンテナ(Ubuntu)
・Xサーバ:macOS
###Xサーバへの接続権限を付与
下記のコマンドを実行し、Xサーバへの接続権限を与える。
$ ip=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}') #macOSのIPを取得
$ xhost + $ip #接続権限の付与
###DISPLAY環境変数、X Windowをオプションで付けてコンテナをRUN
Dockerイメージをbuildしたら下記を実行する。
docker run -p 8888:8888 -e DISPLAY=$ip:0 -e USER=root -v /tmp/.X11-unix:/tmp/.X11-unix -v ~/Desktop/ds_python:/work --name my-lab {イメージID}
ちなみに参照1に記載されているRUNコマンドに以下のオプションを追加したものである。
-vオプション(2つ目)は各自好きなように設定すること。
・-eオプション(1つ目):DISPLAY環境変数の設定、Xサーバへの接続権限を付与したmacOSのIPが入る
・-eオプション(2つ目):コンテナ内のUbuntuユーザをrootに指定
・-vオプション(1つ目):X Windowを接続
#結果
ミッションコンプリート。imshowで画像が表示されるようになりました。
#結論
以下をすることでDockerコンテナ(Ubuntu)でOpenCVのimshowを表示することができた。
・XQuartzの導入・起動
・Xサーバへの接続宣言を付与
・DISPLAY環境変数、X Windowをオプションで付けてコンテナをRUN
#参考ページ
今回の解決にあたって参考となったページは以下の通りである。
・Dockerコンテナの中でGUIアプリケーションを起動させる
・Docker for Macで作ったUbuntuコンテナ内のGUIプログラム(spyder)を使う
・Dockerを導入してGUI操作可能なLinux(Ubuntu)コンテナを作成する