粗大メモ置き場

個人用,たまーに来訪者を意識する雑記メモ

ROSでGPUを有効にしたOpenCVを使用する

前回の記事でOpencvをcudaのサポート込でコンパイルしたわけですが今度はこれをROSで使えるように教えこまないといけません.

ここで問題になるのがOpencv with cudaとRosのOpencv3パッケージの競合です.
自分でコンパイルした方を使いたいのですが,ROSの方にはcv_bridgeを始めとする超重要パッケージもあるので片方を消すわけにも行かない...

以下の記事にもあるように割と根深い問題です.
qiita.com

Step1. findpackageで正しいpathを指定する。

はじめにfindpackageの部分をいじって、OPENCV_LIB等に正しいPATHを認識させます。

cmakelistのfindpackageがどこを見ているのかチェック

ガチの初心者&雰囲気で理解しているので間違っていたらコメントください.
CMakeListでははじめに
findpackage()を呼んでインクルードしたいパッケージのPathを探すようです.
その後,そのPathを用いて目的のソースとライブラリを関連付けます.

${FUGA}の中身を確認するには?

次のような文をprintfよろしく書き連ねることでcmakeをするときにWarning文として出力できます.
多分正攻法ではない気がしますがとにかく動きます.WARNINGをつけているのは該当箇所に黄色い見出しがついて見やすくなるからです。

MESSAGE(WARNING "prefix ${CMAKE_PREFIX_PATH}")    
MESSAGE(WARNING "version ${OpenCV_VERSION}")
MESSAGE(WARNING "install path ${OpenCV_INSTALL_PATH}") 
MESSAGE(WARNING "config path ${OpenCV_CONFIG_PATH}") # look at the output of this message
MESSAGE(WARNING "include dirs ${OpenCV_INCLUDE_DIRS}")
MESSAGE(WARNING "libs ${OpenCV_LIBS}")

OpenCVのPathを指定する

私はcmakeとかLinuxとかガチガチの初心者でしたのでcmakeの中身についてメモをば.
以下のような文を足すことで確かにCmakeにOpencvのデフォルトパッケージの位置を教えることができます.

find_package(OpenCV 3 REQUIRED
NO_MODULE 
PATHS /usr/local 
NO_DEFAULT_PATH)

cmakeとcatkin_makeで結果が違うんだけど!?

そうして試してみると,ある時cmakeでコンパイルした時とcatkin_makeでコンパイルした時で結果が違うことにきづきました.

どうもcatkin_makeでは前回のBuildに依存しているようで,一度Buildとdevelフォルダを消し飛ばす必要があります.
How to tell Catkin_make to use opencv with gpu? - ROS Answers: Open Source Q&A Forum

develをまるごと消すとdarknet_rosとかに不都合が生じるのできちんとバックアップをとっておくように!

そうして再コンパイルしてこの事件は解決...かにおもわれました.

STEP2. catkin_LIBRARIESとの競合解決

問題提起

上記の方法で、
結局ソースコードと正しいOpencvとを関連付けることができませんでした.

原因は最後のLinkに有ると思っています.

target_link_libraries(my_function ${OpenCV_LIBS} ${catkin_LIBRARIES})

このCatkin_librariesがある$catkin_develを見たところ,以下のpathが紛れておりバッチリROSのOpencvを参照していたからです.

/opt/ros/kinetic/include/opencv-3.2.0-dev

ということは,現状次の解決策はROSのOpencvとBuildしたOpencvのうち,被っている箇所のどちらかを吹き飛ばすか,先にBuildした方のOpencvのPathを先に解決させることが考えられます.(小学生並みの希望的観測)

が,どっちもやり方がよくわかんないので誰かおしえてください〜〜〜ってなっているのが現在の状況.

追記:catkin_librariesからROSのopencvを追い出す

cmakeの変数はどれも文字列として扱う事ができるので、そこからROSのOpencvに相当するところだけを頑張って置換する事ができます。

書き方の例は

string(REPLACE "StringYouWantReplace" "ReplacedString" LIBafter "${LIBbefore}" )

こんな感じ。

私の場合、catkin_LIBRARIESからOpencv関連を全てを消し飛ばすのが最も有効でした。
なお、cv_bridge等のパッケージはOpencv2準拠で別枠らしいのでこの方法では支障をきたすことはありません。

string(REPLACE "/opt/ros/kinetic/lib/libopencv_calib3d3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_core3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_features2d3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_flann3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_highgui3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_imgcodecs3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_imgproc3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_ml3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_objdetect3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_photo3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_shape3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_stitching3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_superres3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_video3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_videoio3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_videostab3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_viz3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_aruco3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_bgsegm3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_bioinspired3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_ccalib3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_cvv3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_datasets3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_dpm3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_face3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_fuzzy3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_hdf3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_line_descriptor3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_optflow3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_phase_unwrapping3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_plot3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_reg3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_rgbd3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_saliency3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_stereo3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_structured_light3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_surface_matching3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_text3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_xfeatures2d3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_ximgproc3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_xobjdetect3.so.3.2.0;/opt/ros/kinetic/lib/libopencv_xphoto3.so.3.2.0;" "" catkin_LIBRARIES "${catkin_LIBRARIES}")

フォーラムでクソ長い質問をしたかいがありました。
How to tell Catkin_make to use opencv with gpu? - ROS Answers: Open Source Q&A Forum

テスト用ソース、サンプルプロジェクト

cmakelistsをどう書くと動いたり動かなかったりするのか調べるのに使ったサンプルプロジェクト。良ければどうぞ。
GitHub - YoshiRi/ros_opencv_conflict: Immitate ROS opencv version confliction

未解決問題

  • 何故か色々いじっているうちにimage_pipelineのstereo_image_procが激遅になってしまって非常に悲しい。
  • OpenCVをCudaでコンパイルしたバージョンがROSのバージョンよりも遅い現象がある。OpenCLを有効化していないせい?

user profile overview - OpenCV Q&A Forum

小技集

catkin_make -DOpenCV_INCLUDE_DIRS=/opt/opencv/include

みたいな感じでBuild時に教えることができますが,雑に試した結果はうまく行っていません.

あと、知らなかったんですが

catkin_make --only PROJECT

ってやれば一つのプロジェクトだけコンパイルできるんですね...
これ使えば他との競合を考えずにコンパイルできたかもしれない。

OpenCV バージョン指定

cmakelistで

SET(OCV_VERSION "3.1")
find_package(OpenCV ${OCV_VERSION})

と書けば該当するOpencvを指定できますね。
これも有効な方法でしょう。

checkPackage("OPENCV_CORE" "Error statement")
と打つことで、該当パッケージが入っているのか確認できるのもグッドポイント。

保存用データ

ros-kinetic-oepncv3のライブラリ

opencv_calib3d;opencv_core;opencv_features2d;opencv_flann;opencv_highgui;opencv_imgcodecs;opencv_imgproc;opencv_ml;opencv_objdetect;opencv_photo;opencv_shape;opencv_stitching;opencv_superres;opencv_video;opencv_videoio;opencv_videostab;opencv_viz;opencv_aruco;opencv_bgsegm;opencv_bioinspired;opencv_ccalib;opencv_cvv;opencv_datasets;opencv_dpm;opencv_face;opencv_fuzzy;opencv_hdf;opencv_line_descriptor;opencv_optflow;opencv_phase_unwrapping;opencv_plot;opencv_reg;opencv_rgbd;opencv_saliency;opencv_stereo;opencv_structured_light;opencv_surface_matching;opencv_text;opencv_xfeatures2d;opencv_ximgproc;opencv_xobjdetect;opencv_xphoto

ビルドしたライブラリ

opencv_xphoto;opencv_xobjdetect;opencv_ximgproc;opencv_xfeatures2d;opencv_tracking;opencv_text;opencv_surface_matching;opencv_structured_light;opencv_stereo;opencv_sfm;opencv_saliency;opencv_rgbd;opencv_reg;opencv_plot;opencv_optflow;opencv_line_descriptor;opencv_hdf;opencv_fuzzy;opencv_face;opencv_dpm;opencv_dnn;opencv_datasets;opencv_cvv;opencv_ccalib;opencv_bioinspired;opencv_bgsegm;opencv_aruco;opencv_videostab;opencv_videoio;opencv_video;opencv_superres;opencv_stitching;opencv_shape;opencv_photo;opencv_objdetect;opencv_ml;opencv_imgproc;opencv_imgcodecs;opencv_highgui;opencv_flann;opencv_features2d;opencv_cudev;opencv_cudawarping;opencv_cudastereo;opencv_cudaoptflow;opencv_cudaobjdetect;opencv_cudalegacy;opencv_cudaimgproc;opencv_cudafilters;opencv_cudafeatures2d;opencv_cudacodec;opencv_cudabgsegm;opencv_cudaarithm;opencv_core;opencv_calib3d