プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。

2021/11/16

OpenCV + GStreamer の Docker コンテナを作成

update2022/05/31 event_note2021/11/16 9:17

OpenCV では既定で ffmpeg が使われます。これを gstreamer を使うように設定変更したかったのですが、gstreamer を使うためには OpenCV を自分でビルドしてインストールする必要があるようです。
なので、OpenCV で gstreamer を使うための Dockerfile を作成しました。

環境

  • Ubuntu 20.04
  • Python 3.8.10
  • OpenCV 4.5.3

前置き

python で OpenCV を扱う場合、opencv-python をインストールすれば、OpenCV もインストールされるようです。
試しに以下のコードで OpenCV の情報を確認してみます。

import cv2
print(cv2.__version__)
print(cv2.getBuildInformation())

Video I/OFFMPEGYES になっており、GStreamerNO になっています。

これを、ffmpeg を無効にして、gstreamer を有効にするため、自分で OpenCV のビルドを行います。

注意事項

せっかく自分で OpenCV をビルドしても、opencv-python をインストールすると、デフォルトの OpenCV が使われるようでした。
OpenCV のビルド時に python のパスを適切に設定していれば、opencv-python をインストールしなくても import cv2 が使えるはずなので、opencv-python はインストールしないようにします。

適当な Dockerfile を用意

今回は Ubuntu:20.04 のイメージを使いました。

インストール手順

GStreamer と OpenCV の公式のドキュメントが以下になります。

これを参考にインストールしていきます。

最終的に作成した Dockerfile

大体以下のような感じになりました。
途中参考になったページの URL などをソース内にメモしています。

FROM ubuntu:20.04

# tzdataのタイムゾーン入力を求められないようにする
# https://tmyoda.hatenablog.com/entry/20210124/1611416396
ENV TZ=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN apt update && \
    apt -y install \
    software-properties-common \
    # 必要なパッケージをインストール(必要に応じて取捨選択)
    python3-pip \
    libgl1-mesa-dev \
    libsm6 \
    git \
    wget \
    unzip \
    # OpenCV: Required build dependencies
    cmake \
    python3-dev \
    python3-numpy \
    libavcodec-dev \
    libavformat-dev \
    libswscale-dev \
    libgtk2.0-dev \
    libgtk-3-dev \
    # OpenCV: Optional Dependencies
    libpng-dev \
    libjpeg-dev \
    libopenexr-dev \
    libtiff-dev \
    libwebp-dev \
    # OpenCV のビルド時に -D WITH_QT=ON を設定するために以下が必要だった
    qtbase5-dev \
    qtdeclarative5-dev \
    # gstreamer のインストール
    # https://gstreamer.freedesktop.org/documentation/installing/on-linux.html
    libgstreamer1.0-dev \
    libgstreamer-plugins-base1.0-dev \
    libgstreamer-plugins-bad1.0-dev \
    gstreamer1.0-plugins-base \
    gstreamer1.0-plugins-good \
    gstreamer1.0-plugins-bad \
    gstreamer1.0-plugins-ugly \
    gstreamer1.0-libav \
    gstreamer1.0-doc \
    gstreamer1.0-tools \
    gstreamer1.0-x \
    gstreamer1.0-alsa \
    gstreamer1.0-gl \
    gstreamer1.0-gtk3 \
    gstreamer1.0-qt5 \
    gstreamer1.0-pulseaudio && \
    # aptのクリア
    apt clean && rm -rf /var/lib/apt/lists/*

# OpenCV のビルドとインストール
# https://docs.opencv.org/master/d2/de6/tutorial_py_setup_in_ubuntu.html
# https://toriten1024.hatenablog.com/entry/2018/09/29/012205
# https://dlrecord.hatenablog.com/entry/2017/12/15/145356
# https://atmarkit.itmedia.co.jp/ait/articles/1704/10/news134.html
RUN mkdir opencv && \
    cd /opencv && \
    # OpenCV のダウンロード
    wget https://github.com/opencv/opencv/archive/4.5.3.zip && \
    unzip 4.5.3.zip && \
    # OpenCV の cmake
    cd /opencv/opencv-4.5.3 && \
    mkdir build && \
    cd /opencv/opencv-4.5.3/build && \
    cmake -D CMAKE_BUILD_TYPE=RELEASE \
    -D BUILD_DOCS=OFF \
    -D BUILD_EXAMPLES=OFF \
    -D BUILD_TESTS=OFF \
    -D WITH_1394=OFF \
    -D WITH_GSTREAMER=ON \
    -D WITH_FFMPEG=OFF \
    # cv2.waitKey() を使うためには WITH_QT=ON にする必要があった
    -D WITH_QT=ON \
    .. && \
    # OpenCV のビルド ※ $(nproc) はコア数を返す、make を並列処理させて高速化したい場合は指定する
    #make -j${nproc} && \
    #make -j3 && \
    make && \
    make install && \
    # 後始末
    rm -rf /opencv

# 必要なプラグインをインストール(必要に応じて取捨選択)
RUN pip3 install \
    pyyaml \
    pymongo \
    flask \
    pytest \
    mongomock

# bash起動
CMD [ "/bin/bash" ]

Docker コンテナの起動

上記で作成した Dockerfile をビルドしたらコンテナを起動します。
カメラにアクセスできるよういろいろ指定していますが、ここらへんは環境に応じて変更してください。

xhost +local:docker

docker run -it --rm \
       --name containername \
       -e DISPLAY=${DISPLAY} \
       -v /tmp/.X11-unix/:/tmp/.X11-unix/ \
       -v /dev/bus/usb:/dev/bus/usb \
       --privileged --device /dev/dri:/dev/dri \
       --device-cgroup-rule='c 189:* rmw' \
       -v $(pwd)/workspace:/workspace \
       --workdir="/workspace" \
       imagename:latest

実際に OpenCV と GStreamer が使えるかどうかの動作確認に別の記事で書きました。