13
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

OpenCVAdvent Calendar 2021

Day 5

OpenCVのプラグイン機能

Last updated at Posted at 2021-12-04

この記事はOpenCV Advent Calendar 2021の5日目の記事です。

はじめに

従来、OpenCVのcv::parallel_for_ backend、highgui backend、videoio backendはOpenCVインストール時に決定されてしまうため、OpenCVインストール後にbackendを変更しようと思うとOpenCVのビルドオプションを変更して再インストールする必要がありました。

OpenCV 4.5.xからプラグイン機構が導入され、OpenCVインストール後にこれらのbackendを動的に変更することができるようになりました。OpenCV 4.5.4時点で用意されているプラグインは以下のとおりです

  • threadingプラグイン
    • cv::parallel_for_ backendを動的に変更できるプラグイン
  • highguiプラグイン
    • highgui backendを動的に変更できるプラグイン
  • videoioプラグイン
    • videoio backendを動的に変更できるプラグイン

とはいえ、なぜプラグイン機構を導入するに至ったかの経緯が気になってきます。https://docs.opencv.org/4.5.3/d0/d3d/tutorial_general_install.html#tutorial_general_install_plugins_4には以下の記述があります。

It is possible to decouple some of OpenCV dependencies and make them optional by extracting parts of the code into dynamically-loaded plugins. It helps to produce adaptive binary distributions which can work on systems with less dependencies and extend functionality just by installing missing libraries.

プラグインとして切り離しておき動的にロードする仕組みにしておけば、それぞれの環境に合ったプラグインを使用する形態にでき、依存ライブラリが入っていなくてプログラムが動かないなどのトラブルが減らせそうなことが書いてあります。

ということで、今回はOpenCVのプラグイン機能について簡単に紹介したいと思います。

threadingプラグイン

threadingプラグインを使うことでcv::parallel_for_のバックエンドを動的に変更することができるようになります。OpenCV 4.5.2以降のバージョンでthreadingプラグインを使用することができます。

threadingプラグイン有効化

OpenCVビルド時にPARALLEL_ENABLE_PLUGINS=ONにしておき、プラグイン機能を有効にします。

CMakeオプション デフォルト値 オプションの意味
PARALLEL_ENABLE_PLUGINS ON threadingプラグインサポートの有効化、無効化を指定

threadingプラグイン生成

threadingプラグインを生成します。https://docs.opencv.org/4.5.3/d0/d3d/tutorial_general_install.html#tutorial_general_install_plugins_4にはCMakeオプションが以下のように紹介されています

cmake -G<generator> \
    -DOPENCV_PLUGIN_NAME=opencv_core_tbb_<suffix> \
    -DOPENCV_PLUGIN_DESTINATION=<dest-folder> \
    -DCMAKE_BUILD_TYPE=<config> \
    <opencv>/modules/core/misc/plugins/parallel_tbb

今回は以下のようなコマンドでMakefileを生成しました。

cmake -G"Unix Makefiles" \
    -DOPENCV_PLUGIN_NAME=opencv_core_tbb_1 \
    -DOPENCV_PLUGIN_DESTINATION=$HOME/opencv_plugin \
    -DCMAKE_BUILD_TYPE=Release \
    $HOME/dev/opencv-4.5.3/modules/core/misc/plugins/parallel_tbb

その後、

make

を実行すると$HOME/opencv_plugin以下にlibopencv_core_tbb_1.soが生成されます(今回、suffixは適当に1を付けただけなので深い意味はありません)。

threadingプラグインの使い方

先程生成したthreadingプラグイン(前述の例だとlibopencv_core_tbb_1.so)をOpenCVライブラリが配置されているパスに格納します。

TBBを使う場合

cv::parallel_for_のバックエンドとしてTBBを使う場合のサンプルコードを以下に示します。

// TBB backendを使う場合はインクルードする
#include <opencv2/core/parallel/backend/parallel_for.tbb.hpp>

int main()
{
    // cv::parallel_for_のバックエンドとしてTBBを使う
    cv::parallel::setParallelForBackend(std::make_shared<cv::parallel::tbb::ParallelForBackend>());

    return 0;
}

https://docs.opencv.org/4.5.4/de/d55/group__core__parallel__backend.html#ga7791f3c18e50f00b5fa88ac9d44cd52fにも以下の記載があり、cv::parallel::setParallelForBackendの呼び出しについては注意が必要です。

This call is not thread-safe. Consider calling this function from the main() before any other OpenCV processing functions (and without any other created threads).

OpenMPを使う場合

cv::parallel_for_のバックエンドとしてOpenMPを使う場合のサンプルコードを以下に示します。
前述の通り、cv::parallel::setParallelForBackendの呼び出しについては注意が必要です。

// OpenMP backendを使う場合はインクルードする
#include <opencv2/core/parallel/backend/parallel_for.openmp.hpp>

int main()
{
    // cv::parallel_for_のバックエンドとしてOpenMPを使う
    cv::parallel::setParallelForBackend(std::make_shared<cv::parallel::openmp::ParallelForBackend>());

    return 0;
}

highguiプラグイン

highguiプラグインを使うことでhighguiモジュールのバックエンドを動的に変更することができるようになります。OpenCV 4.5.3以降のバージョンでhighguiプラグインを使用することができます。

highguiプラグイン有効化

OpenCVビルド時にHIGHGUI_ENABLE_PLUGINS=ONにしておき、プラグイン機能を有効にします。

CMakeオプション デフォルト値 オプションの意味
HIGHGUI_ENABLE_PLUGINS ON highguiプラグインサポートの有効化、無効化を指定
HIGHGUI_PLUGIN_LIST empty バックエンド名をカンマ、もしくはセミコロンで区切って指定します。gtk, gtk2, gtk3が選択できます

HIGHGUI_PLUGIN_LISTに関して、

gtk, gtk2, gtk3が選択できます

はOpenCVドキュメントにある情報ですが、https://github.com/opencv/opencv/pull/20281を読むとわかるようにhttps://github.com/opencv/opencv/blob/4.5.4/modules/highgui/cmake/init.cmake#L39

add_backend("win32ui" WITH_WIN32UI)

とあるので、HIGHGUI_PLUGIN_LISTにwin32uiが指定できそうです(ドキュメントの更新漏れ?)。

また、https://github.com/opencv/opencv/blob/4.5.4/modules/highgui/cmake/init.cmake#L40-L42を読むと以下のようになっているので、OpenCV 4.5.4時点でCocoa、Qt対応などはまだのようです。

# TODO cocoa
# TODO qt
# TODO opengl

highguiプラグイン生成

highguiプラグインを生成します。
今回は以下のようなコマンドでMakefileを生成しました。

cmake -G"Unix Makefiles" \
    -DOPENCV_PLUGIN_NAME=opencv_highgui_gtk_3 \
    -DOPENCV_PLUGIN_DESTINATION=$HOME/opencv_plugin \
    -DCMAKE_BUILD_TYPE=Release \
    $HOME/dev/opencv-4.5.3/modules/highgui/misc/plugins/plugin_gtk

その後、

make

を実行すると$HOME/opencv_plugin以下にlibopencv_highgui_gtk_3.soが生成されます(今回、suffixは適当に3を付けただけなので深い意味はありません)。

highguiプラグインの使い方

先程生成したhighguiプラグイン(前述の例だとlibopencv_highgui_gtk_3.so)をOpenCVライブラリが配置されているパスに格納します。

videoioプラグイン

videoioプラグインを使うことでvideoioモジュールのバックエンドを動的に変更することができるようになります。

videoioプラグイン有効化

OpenCVビルド時にVIDEOIO_ENABLE_PLUGINS=ONにしておき、プラグイン機能を有効にします。

CMakeオプション デフォルト値 オプションの意味
VIDEOIO_ENABLE_PLUGINS ON videoioプラグインサポートの有効化、無効化を指定
VIDEOIO_PLUGIN_LIST empty バックエンド名をカンマ、もしくはセミコロンで区切って指定します。ffmpeg, gstreamer, msmf, mfxが選択できます

VIDEOIO_PLUGIN_LISTに関して、

ffmpeg, gstreamer, msmf, mfxが選択できます

はOpenCVドキュメントにある情報ですが、https://github.com/opencv/opencv/blob/4.5.4/modules/videoio/cmake/init.cmake#L11-L33を読むと以下のようになっています。

add_backend("ffmpeg" WITH_FFMPEG)
add_backend("gstreamer" WITH_GSTREAMER)
add_backend("v4l" WITH_V4L)

add_backend("aravis" WITH_ARAVIS)
add_backend("dc1394" WITH_1394)
add_backend("gphoto" WITH_GPHOTO2)
add_backend("msdk" WITH_MFX)
add_backend("openni2" WITH_OPENNI2)
add_backend("pvapi" WITH_PVAPI)
add_backend("realsense" WITH_LIBREALSENSE)
add_backend("ueye" WITH_UEYE)
add_backend("ximea" WITH_XIMEA)
add_backend("xine" WITH_XINE)

add_backend("avfoundation" WITH_AVFOUNDATION)
add_backend("ios" WITH_CAP_IOS)

add_backend("dshow" WITH_DSHOW)
add_backend("msmf" WITH_MSMF)

add_backend("android_mediandk" WITH_ANDROID_MEDIANDK)
add_backend("android_camera" WITH_ANDROID_NATIVE_CAMERA)

これだけ見るとVIDEOIO_PLUGIN_LISTで指定できるパラメータがドキュメント記載のものよりも揃っているように見えます。時間の都合上、ドキュメントに記載のないフレームワークを指定しても動作するかの確認までできていないのでドキュメントの更新漏れなのかどうかはわかりません。

videoioプラグイン生成

videoioプラグインを生成します。
今回は以下のようなコマンドでMakefileを生成しました。

cmake -G"Unix Makefiles" \
    -DOPENCV_PLUGIN_NAME=opencv_videoio_ffmpeg_3 \
    -DOPENCV_PLUGIN_DESTINATION=$HOME/opencv_plugin \
    -DCMAKE_BUILD_TYPE=Release \
    $HOME/dev/opencv-4.5.3/modules/videoio/misc/plugin_ffmpeg

その後、

make

を実行すると$HOME/opencv_plugin以下にlibopencv_videoio_ffmpeg_3.soが生成されます(今回、suffixは適当に3を付けただけなので深い意味はありません)。

videoioプラグインの使い方

先程生成したvideoioプラグイン(前述の例だとlibopencv_videoio_ffmpeg_3.so)をOpenCVライブラリが配置されているパスに格納します。

おわりに

本記事では最近OpenCVに追加されたプラグイン機能について紹介しました。OpenCV 4.5.4時点だと一部バックエンドのみのサポートではありますが、揃ってくると配布時に便利なケースも出てきそうです。

参考URL

関連PR

公式チュートリアル

13
6
0

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
13
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?