DockerのコンテナでOpenCV(C++)開発環境を構築する
DockerのコンテナでOpenCV(C++)を実行する
dockerのコマンドに新コマンド体系ができたそうだ。
新コマンド体系は動作の内容がわかりやすいが、入力が面倒。
今回は新コマンドになれるために新コマンドで作業を行った。
参考:docker container / image コマンド新旧比較 - Qiita
Dockerの導入
導入方法は以下。
kinacon.hatenablog.com
sudoの省略
cat /etc/group #グループ一覧 sudo groupadd docker #dockerグループ一覧を追加 sudo gpasswd -a $USER docker #dockerグループにuserを追加 sudo service docker restart #dockerデーモンを再起動 exit #再ログイン
WARNINGが出る場合
WARNING: Error loading config file: /home/user/.docker/config.json: stat /home/user/.docker/config.json: permission denied
既にsudoで実行していると所有者rootで.dockerが作られているので所有者をuserに変更する。
sudo chown -R user ~/.docker
docker.sockのエラー
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.38/images/json: dial unix /var/run/docker.sock: connect: permission denied
以下のコマンドとPCの再起動で治った。(多分、再起動だけでいいかも)
sudo chgrp docker /var/run/docker.sock
Dockerのversion確認
docker version
コンテナ作成
ベースイメージをpullする
ベースイメージは16.04にしました。
docker image pull ubuntu:16.04
イメージの確認
docker image ls
コンテナ起動
docker container run -it ubuntu:16.04
コンテナ起動後(OSの確認)
cat /etc/os-release
C++開発環境を構築
GUIが使用できないためエディタはnanoを利用。
apt update apt install build-essential cmake nano
※今回のaptのインストールパッケージは「インストールまとめ」にまとめてあります。
OpenCV導入(ソースからライブラリのビルド)
今回はソースからビルドします。
関連パッケージのインストール
ソース取得、展開用 | ca-certificates unzip wget |
---|---|
ビルド用 | pkg-config |
GUI用 | libgtk2.0-dev |
画像の読み書き用 | apt install libjpeg-dev libpng-dev |
動画の読み書き用 | ffmpeg libavcodec-dev libavformat-dev libavresample-dev libswscale-dev |
Usbカメラ取り込み用 | libv4l-dev |
TBBによる並列化を有効化用 | libtbb-dev |
OpenCVのインストール
OpenCVのバージョンは3.4.3です。
以下リリースバージョン
Releases - OpenCV library
ビルド時のログをteeで保存しています。
※OPENCV_VERSIONを変更してバージョン変更できます。
OPENCV_VERSION="3.4.3" mkdir -p /tmp/opencv && cd /tmp/opencv wget https://github.com/opencv/opencv/archive/${OPENCV_VERSION}.zip unzip ${OPENCV_VERSION}.zip -d . mkdir /tmp/opencv/opencv-${OPENCV_VERSION}/build && cd /tmp/opencv/opencv-${OPENCV_VERSION}/build/ cmake -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D WITH_FFMPEG=ON -D WITH_TBB=ON .. | tee /tmp/opencv_cmake.log make -j "$(nproc)" | tee /tmp/opencv_build.log make install | tee /tmp/opencv_install.log
OpenCVのバージョン確認
pkg-config --modversion opencv
ソースファイルを削除(コンテナを軽くする)
cd && rm -rf /tmp/opencv
コンテナを一旦exit(STOP)
exit
コンテナIDを確認してコンテナをcommit(イメージとして保存)
docker container ls -a docker container commit [コンテナID] [イメージ名](:[タグ])
チュートリアル実行
事前にチュートリアルはホスト環境で実行確認した。
kinacon.hatenablog.com
コンテナ(環境整備済み)から画像を表示できるようにGUIの設定する。
また、動作確認用プログラム(ソースとcmakelists)をコンテナ内のディレクトリにコピーする
コンテナ(環境整備済み)を起動
docker container run -it --rm \ -v /tmp/.X11-unix/:/tmp/.X11-unix \ -e DISPLAY=$DISPLAY \ [イメージ名](:[タグ])
一旦抜けて(ctl+p、ctl+q)コンテナのIDを確認
docker container ls -a
コンテナからXサーバへの通信を許可
xhost +local:`docker inspect --format='{{ .Config.Hostname }}' [コンテナID]`
コンテナにソースファイルとcmakeファイルをコピー
cd c++/cv_tutorial/ docker container cp CMakelists.txt [コンテナID]:/tmp/ docker container cp DisplayImage.cpp [コンテナID]:/tmp/
コンテナに入る
docker attach [コンテナID]
ビルドして実行
cd /tmp/ mkdir build cd build cmake .. make ./Display ****.png
画像が表示できればOK。
インストールまとめ
※apt 使用時にコンテナ容量を減らす
--no-install-recommendsをつけてインストールする(必須パッケージのみインストール)
最後にapt clean でキャシュを削除
apt update apt install --no-install-recommends -y build-essential cmake nano \ ca-certificates unzip wget \ pkg-config \ libgtk2.0-dev \ libjpeg-dev libpng-dev \ ffmpeg libavcodec-dev libavformat-dev libavresample-dev libswscale-dev \ libv4l-dev \ libtbb-dev apt clean
proxy環境の場合
aptの設定
編集ファイル | /etc/apt/apt.conf |
---|
追記内容 |
---|
Acquire::http::proxy "http://id:pass@proxy_address:port/"; |
Acquire::https::proxy "https://id:pass@proxy_address:port/"; |
cat <<EOF >> /etc/apt/apt.conf Acquire::http::proxy "http://id:pass@proxy_address:port/"; Acquire::https::proxy "https://id:pass@proxy_address:port/"; EOF
wgetの設定
編集ファイル | /etc/wgetrc |
---|
追記内容 |
---|
https_proxy = http://id:pass@proxy_address:port/ |
http_proxy = http://id:pass@proxy_address:port/ |
ftp_proxy = http://id:pass@proxy_address:port/ |
cat <<EOF >> /etc/wgetrc https_proxy = http://id:pass@proxy_address:port/ http_proxy = http://id:pass@proxy_address:port/ ftp_proxy = http://id:pass@proxy_address:port/ EOF
DockerでGUIアプリケーションを実行するための設定
参考:Dockerコンテナの中でGUIアプリケーションを起動させる | Unskilled?
ドメインソケットの共有
-v /tmp/.X11-unix/:/tmp/.X11-unix
DISPLAY変数をコンテナのDISPLAY変数に入れる
-e DISPLAY=$DISPLAY
XサーバーにおけるXクライアントの許可
すべてのクライアントからの通信を許可
xhost +
ローカルからの通信を許可
xhost local:
特定のコンテナ(コンテナのホスト名)だけ許可
xhost +local:`docker container inspect --format='{{ .Config.Hostname }}' [コンテナID]`
dockerコマンド
コンテナの一覧表示(稼働中のみ、停止中を含める場合は-aをつける) |
---|
docker container ls |
ホストからコンテナにファイルをコピーする |
docker container cp ソース [コンテナID]:格納先ディレクトリ |
コンテナ実行にコンテナから抜ける(STATUS:UP) |
ctl+p ctl+q |
コンテナ実行にコンテナから抜ける(STATUS:Exited) |
exit |
実行中のコンテナ(STATUS:UP)に入る |
docker container attach [コンテナID] |
停止中のコンテナを起動する(STATUS:Exited → UP) |
docker container start [コンテナID] |
実行中のコンテナをストップする(STATUS:UP → Exited) |
docker container stop [コンテナID] |
停止中のコンテナを削除する |
docker container rm [コンテナID] |
停止中のすべてのコンテナを削除する |
docker container prune |
コンテナをイメージに保存する |
docker container commit [コンテナID] |
イメージの一覧表示 |
docker image ls |
イメージの削除 |
docker image rm |
使用していないイメージを一括削除 |
docker image prune |
docker container run のオプション
イメージから新規コンテナを起動 |
---|
docker container run [イメージ名](:[タグ]) |
オプション | |
---|---|
-i | ホストの入力をコンテナの標準入出力につなげる |
-t | tty(標準入出力となっている端末デバイス)を使う |
-e | 環境変数を渡す |
--rm | コンテナ終了時に自動で削除する |
-v /ホストディレクトリ:/コンテナのディレクトリ | ホストのディレクトリをコンテナのディレクトリにマウントする(共有する) |
以上。