OpenCV4.9.0×Qt5.15.2のビルド
久しぶりにimshowで表示した画像をズームする必要が生じたので、Qtを含めたビルドをしようとしたものの、何故か過去に実施した際のビルド設定では失敗しました。
イチからやり直しましたので、備忘録がてら記録を。
CMake、Visual Studio、OpenCV、OpenCV contribはOpenCV/4.8.0のビルドのとおりですが、OpenCV関係はバージョンアップされてますので4.9.0を使用します。
Qtは、まず公式サイトからオープンソース版のインストーラをダウンロードします。
インストーラを実行すると、インストールするバージョンやコンポーネントの選択画面が出てきますので、「Archive」にチェックを入れて「フィルター」をクリックし、「Qt5.15.2」の「MSVC 2019 64-bit」だけにチェックを入れてインストールします。
なお、そろそろQt6系にも対応してくれたかなと期待して、現時点で最新バージョンの6.6.2でも試してみましたがOpenCVのビルドはできませんでした。
あとは、環境変数のPathに「[Qtインストール場所]\5.15.2\msvc2019_64\bin」を設定して、Qtの準備は完了です。
また、別件でFFmpeg以外のvideoioバックエンドを使って遊びたかったので、今回は以下のサイトを参考にGStreamerも含めました。
次に、CMakeの設定ですが、まずは以下の設定を行います。
- BUILD_opencv_world にチェック
- OPENCV_EXTRA_MODULE_PATH に [contribの配置場所]/module を設定
- WITH_GSTREAMER にチェック
- WITH_QT にチェック
- 私のように別件で構築したJavaやPython環境が邪魔という方は、以下の設定のチェックを全て外す
この状態でConfigureを実行すると、特にエラーは出ないと思いますし、Pathが通せていれば他に設定せずとも、QtとGStreamerのValueには適切なパラメータが反映されると思います。
が、しかし、このままビルドすると、cvv::gui::CallTabほか多数でLNK2001のエラーが生じました。
cvvは「GUI for Interactive Visual Debugging of Computer Vision Programs」、つまりデバッグ用GUIツールなのですが、どうもこれを含めているとビルドでこけるようです。
なので、以下の設定を追加で行い、再度Configure。
- BUILD_opencv_cvv のチェックを外す
あとはGenerate⇒Open Project⇒ビルドのお決まりの流れで完了です。
えー…余談となりますが、そもそもimshowで表示した画像をズームしたかった理由は、画像上の任意の点を選択する機能を持ったプログラムを作成したかったからなのですが、上記のとおり素直にビルドし、imshowで表示したウィンドウ上でマウスホイールをくるくるっと操作してズームしてみると…あら不思議、マウスカーソルが矢印から手に変わりますよね。
クリックして座標選択するのにはものすごく不向きなマウスカーソルです。
というわけで、実際には、ビルドする前に「highgui/src/window_QT.cpp」のコードを以下のとおり修正しました。
- DefaultViewPort::mousePressEvent の setCursor(Qt::ClosedHandCursor); を setCursor(Qt::ArrowCursor); に変更
- DefaultViewPort::mouseReleaseEvent 及び DefaultViewPort::scaleView の setCursor(Qt::OpenHandCursor); を setCursor(Qt::ArrowCursor); に変更
動作確認用に使用したテストコードは以下のとおりです。
#include<opencv2/opencv.hpp> using namespace cv; void onMouse(int event, int x, int y, int flag, void*); Mat canvas = imread("lena.jpg"); int main() { namedWindow("image", WINDOW_NORMAL | WINDOW_KEEPRATIO | WINDOW_GUI_NORMAL); setMouseCallback("image", onMouse, 0); while (true) { imshow("image", canvas); int key = waitKey(1); if (key == 27) { break; } } destroyWindow("image"); return 0; } void onMouse(int event, int x, int y, int flag, void*) { switch (event) { case EVENT_LBUTTONDOWN: circle(canvas, Point(x, y), 0, Scalar::all(0), 0, LINE_4, 0); break; } }
実行結果は以下のとおりです。
左から順に初期表示、ズーム時、マウスクリック時ですが、クリックした座標に黒色の点を描画することができていますので、これで細かな座標指定が実現できるはずです。
OpenCV/4.8.0のビルド
日本時間で6/29の午前2時頃でしょうか、OpenCVのver.4.8.0がReleaseされました。
自分の備忘録+超初心者にもわかるように・を意識して手順を記録しておこうと思います。
CMake、Visual Studioは予め用意しておくこととします。
私の環境では、CMake 3.22.2、Visual Studio 2022 Professionalを利用しています。
はじめに、OpenCVライブラリのダウンロード。
今回はとりあえずCUDAとかQtとかは無しで、拡張ライブラリ(contrib)のみのシンプルなビルドを行いますので、以下リンクからzipファイルをダウンロードします。
いずれも「Code」の「Download ZIP」をクリックしたら取得できます。
解凍したら「opencv-4.8.0」と「opencv_contrib-4.8.0」が出てきますので、扱いやすいところに配置します。
なお、以降の説明で出てくるパス設定等は、以下に示す私の環境におけるものですので、異なる配置の場合は読み替えるようにしてください。
C:
├ _develop_lib
│ ├ opencv
│ │ ├ opencv-4.8.0
│ │ └ opencv_contrib-4.8.0
│ └ opencv_build
│ └ 4.8.0
└ opencv
└ 4.8.0
ざっくりまとめると、ダウンロードしたものは「C:\_develop_lib\opencv」、ビルドしたものは「C:\_develop_lib\opencv_build」、本番利用するものは「C:\opencv」にそれぞれ配置するようにしています。
次に、CMakeの設定ですが、超初心者にもわかるように・がモットーなので、GUI版で説明します。
「Where is the source code:」にOpenCV本体のパス、「Where to build the binaries:」にビルド結果保存先のパスをそれぞれ設定し、「Configure」をクリックすると子画面が出てきてVisual Studioのバージョンを設定するように促してくるので、適切なバージョンを選択して「Finisih」をクリックします。
しばらくは以下のような画面が表示されます。
終わると画面下部のメッセージボックスに「Configure done」と表示され、ビルドパラメータの設定ができるようになります。
今回はシンプル設定なので、以下の設定だけ行って、再度「Configure」をクリックします。
- BUILD_oepncv_world にチェック
- CMAKE_INSTALL_PREFIX … C:/_develop_lib/opencv_build/4.8.0/install
- OPENCV_EXTRA_MODULES_PATH … C:/_develop_lib/opencv/opencv_contrib-4.8.0/modules
変なエラーとかが出ることもなく、きちんと「Configure done」が表示されたら「Generate」をクリックします。
ちなみに私の環境だと、最終的に以下のようなメッセージが出力されています。
General configuration for OpenCV 4.8.0 ===================================== Version control: unknown Extra modules: Location (extra): C:/_develop_lib/opencv/opencv_contrib-4.8.0/modules Version control (extra): unknown Platform: Timestamp: 2023-06-29T12:11:58Z Host: Windows 10.0.22621 AMD64 CMake: 3.22.2 CMake generator: Visual Studio 17 2022 CMake build tool: C:/Program Files/Microsoft Visual Studio/2022/Professional/MSBuild/Current/Bin/amd64/MSBuild.exe MSVC: 1936 Configuration: Debug Release CPU/HW features: Baseline: SSE SSE2 SSE3 requested: SSE3 Dispatched code generation: SSE4_1 SSE4_2 FP16 AVX AVX2 AVX512_SKX requested: SSE4_1 SSE4_2 AVX FP16 AVX2 AVX512_SKX SSE4_1 (18 files): + SSSE3 SSE4_1 SSE4_2 (2 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 (1 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 AVX AVX (8 files): + SSSE3 SSE4_1 POPCNT SSE4_2 AVX AVX2 (37 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2 AVX512_SKX (8 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2 AVX_512F AVX512_COMMON AVX512_SKX C/C++: Built as dynamic libs?: YES C++ standard: 11 C++ Compiler: C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.36.32532/bin/Hostx64/x64/cl.exe (ver 19.36.32532.0) C++ flags (Release): /DWIN32 /D_WINDOWS /W4 /GR /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi /fp:precise /EHa /wd4127 /wd4251 /wd4324 /wd4275 /wd4512 /wd4589 /wd4819 /MP /MD /O2 /Ob2 /DNDEBUG C++ flags (Debug): /DWIN32 /D_WINDOWS /W4 /GR /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi /fp:precise /EHa /wd4127 /wd4251 /wd4324 /wd4275 /wd4512 /wd4589 /wd4819 /MP /MDd /Zi /Ob0 /Od /RTC1 C Compiler: C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.36.32532/bin/Hostx64/x64/cl.exe C flags (Release): /DWIN32 /D_WINDOWS /W3 /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi /fp:precise /MP /MD /O2 /Ob2 /DNDEBUG C flags (Debug): /DWIN32 /D_WINDOWS /W3 /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi /fp:precise /MP /MDd /Zi /Ob0 /Od /RTC1 Linker flags (Release): /machine:x64 /INCREMENTAL:NO Linker flags (Debug): /machine:x64 /debug /INCREMENTAL ccache: NO Precompiled headers: NO Extra dependencies: 3rdparty dependencies: OpenCV modules: To be built: aruco bgsegm bioinspired calib3d ccalib core datasets dnn dnn_objdetect dnn_superres dpm face features2d flann fuzzy gapi hfs highgui img_hash imgcodecs imgproc intensity_transform line_descriptor mcc ml objdetect optflow phase_unwrapping photo plot python3 quality rapid reg rgbd saliency shape stereo stitching structured_light superres surface_matching text tracking ts video videoio videostab wechat_qrcode world xfeatures2d ximgproc xobjdetect xphoto Disabled: - Disabled by dependency: - Unavailable: alphamat cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev cvv freetype hdf java julia matlab ovis python2 python2 sfm viz Applications: tests perf_tests apps Documentation: NO Non-free algorithms: NO Windows RT support: NO GUI: Win32 UI: YES VTK support: NO Media I/O: ZLib: build (ver 1.2.13) JPEG: build-libjpeg-turbo (ver 2.1.3-62) SIMD Support Request: YES SIMD Support: NO WEBP: build (ver encoder: 0x020f) PNG: build (ver 1.6.37) TIFF: build (ver 42 - 4.2.0) JPEG 2000: build (ver 2.5.0) OpenEXR: build (ver 2.3.0) HDR: YES SUNRASTER: YES PXM: YES PFM: YES Video I/O: DC1394: NO FFMPEG: YES (prebuilt binaries) avcodec: YES (58.134.100) avformat: YES (58.76.100) avutil: YES (56.70.100) swscale: YES (5.9.100) avresample: YES (4.0.0) GStreamer: NO DirectShow: YES Media Foundation: YES DXVA: YES Parallel framework: Concurrency Trace: YES (with Intel ITT) Other third-party libraries: Intel IPP: 2021.8 [2021.8.0] at: C:/_develop_lib/opencv_build/4.8.0/3rdparty/ippicv/ippicv_win/icv Intel IPP IW: sources (2021.8.0) at: C:/_develop_lib/opencv_build/4.8.0/3rdparty/ippicv/ippicv_win/iw Lapack: NO Eigen: NO Custom HAL: NO Protobuf: build (3.19.1) Flatbuffers: builtin/3rdparty (23.5.9) OpenCL: YES (NVD3D11) Include path: C:/_develop_lib/opencv/opencv-4.8.0/3rdparty/include/opencl/1.2 Link libraries: Dynamic load Python 3: Interpreter: C:/_tool/anaconda3/python.exe (ver 3.10.9) Libraries: C:/_tool/anaconda3/libs/python310.lib (ver 3.10.9) numpy: C:/_tool/anaconda3/lib/site-packages/numpy/core/include (ver 1.23.5) install path: C:/_tool/anaconda3/Lib/site-packages/cv2/python-3.10 Python (for build): C:/_tool/anaconda3/python.exe Java: ant: NO Java: NO JNI: NO Java wrappers: NO Java tests: NO Install to: C:/_develop_lib/opencv_build/4.8.0/install
PythonのところにAnaconda3の設定が表示されちゃってますが、別件で遊んでたのが読み込まれちゃっただけなので気にしないでください。
このように「Generating done」が表示されたら、「Where to build the binaries:」で指定したパスに「OpenCV.sln」ができています。
いよいよビルド作業です。
「OpenCV.sln」を開き、「ビルド>バッチビルド」を選択、「ALL_BUILD」と「INSTALL」を探し、それぞれ「Debug」と「Release」の両方(計4か所)にチェックを入れたら「ビルド」をクリックするだけです。
あとは終わるのを待つだけです。
エラーさえ無ければ大丈夫なことが多いです。
なお、今回は以下のようなエラーがありましたが、Pythonを使う気は全く無いので無問題として無視します。
「CMAKE_INSTALL_PREFIX」で設定したパスに成果物ができているはずですので、本番利用するつもりの場所(あとでパスを通します)に配置します。
私の環境ですと(わかりやすさのために3階層目以下は省略していますが)以下のような配置になっています。
C:\opencv\4.8.0>tree | findstr /R /C:"^├" /C:"^│ ├" /C:"^│ └" /C:"^└" ├─bin ├─etc │ ├─haarcascades │ ├─lbpcascades │ └─licenses ├─include │ └─opencv2 └─x64
キーボードでWin+pauseを押し、「システムの詳細設定」から「環境変数」を選択します。
「Path」を選択して「編集」をクリックし、以下のように設定すれば完了です。
あとは、以下を参考にプロジェクト側で設定すれば準備完了です。
動作確認として、以下のコードを実行しました。
#include<opencv2/opencv.hpp> #include<iostream> #include<string> #include<filesystem> namespace fs = std::filesystem; int main() { std::cout << cv::getBuildInformation(); fs::path imgPath = "lena512.jpg"; cv::Mat srcImg = cv::imread(imgPath.string()); std::string wnd_name = "image"; cv::namedWindow(wnd_name, cv::WINDOW_AUTOSIZE | cv::WINDOW_KEEPRATIO | cv::WINDOW_GUI_NORMAL); while (true) { cv::imshow(wnd_name, srcImg); int key = cv::waitKey(1); if (key == 27) { break; } } cv::destroyWindow(wnd_name); return 0; }
OpenCV/YOLO学習済みモデルの利用方法
深層学習、いわゆるディープラーニングを使用した画像処理が脚光を浴び始めてから結構経った気がします。
私は大学で画像関係の研究をしていましたが、当時勉強したSIFTとかHOGといった特徴量ベースの物体検出・認識はすっかり過去のものという雰囲気を感じて少し寂しい気もしています。
さて、ディープラーニングのプログラミング言語といえばPython!というのも、また広く知れ渡っている事実だと思います。
私自身、現在も画像関係の仕事をしているため、「そろそろPython環境をきっちり構築して真面目にディープラーニングの勉強に取り組もうかな」と思い続けているのですが、長らくWindows、C言語(C++)、VisualStudio、OpenCVという環境で遊んできたので、ついつい「新しい言語は面倒だなぁ」と感じて諸事情により職場にはインターネット接続できるパソコンがないため、Pythonだと環境構築が非常に困難かつ面倒なので二の足を踏んでいる状態です。
しかしながら、ディープラーニングを使うことで、使わないときとは比較にならないくらいお手軽かつ高精度に処理できるものが多々あることはわかりきっています。
そこで、ひとまずPythonのことは置いといて、ディープラーニングを利用することで受ける恩恵がどんなものかを知るために、学習済みモデルを使って物体検出プログラムを動かしてみようと思います。
OpenCVでは、dnnというモジュール内の機能を使うことでディープラーニングによる学習済みモデルを使った処理を実現でき、公式ドキュメントを見るとCaffe、TensorFlow、Torch、Darknet、DLDT、ONNXに対応していることがわかります。
OpenCV: Deep Neural Network module
後ほど登場するOpenCVのサンプルではYOLOという物体検出アルゴリズムを使用し、Darknetというフレームワークの学習モデル形式を使っていますので、ここでも同様にします。
私の開発環境は以下のとおりです。
- OS:Windows 11 Pro
- CPU:Intel Core i9-10920X 3.50 GHz
- RAM:64.0 GB (CFD W4U26666CX1-16GB x4)
- G/B:Geforce RTX 3060 (ASUS ROG-STRIX-RTX3060-O12G-GAMING)
- IDE:Visual Studio 2022 Professional
IDEですが、私の場合はオフラインでも使えるようにと有償版のProfessionalを利用していますが、オンライン環境下であれば無料版であるCommunityを使用しても問題ありません。
そして、開発言語ですが、もちろんPythonは使わずC++です。
OpenCVのバージョンは4.6.0(本記事の投稿時点では最新)で、公式サイトのLibrary -> Releases -> Windowsとリンクを辿ってダウンロードできるexe形式のものではなく、Gitから追加モジュールであるcontribを含めてダウンロードし、CMakeでビルドしたものを利用しています。
少し古い(2017年9月21日)ですが、contribについては以下の記事でわかりやすく紹介してくれていますし、記事中で紹介されているリンクを辿ってOpenCVのExampleを見てるだけでも結構楽しいのでおすすめです。
物体検出プログラムのコードはOpenCVのサンプルをほぼそのまま使います。
OpenCV: samples/dnn/object_detection.cpp
「ほぼ」そのままと言っていますが、そのままだと動かないとかではなく、個人的に使いにくいと感じたところを自分好みに書き換えただけで、変更点は以下の4点だけです。
- 検出結果が人物のものだけを描画(たくさん枠が描画されると邪魔)
- コマンドライン引数の一部(modelPathとconfigPath)をコード内で定義
- namdeWindowのオプション(WINDOW_NORMAL -> WINDOW_AUTOSIZE)
- 処理結果映像をVideoWriterで書き出し
あと必要となるものは、処理対象映像ファイルを除くと学習済みモデル関係です。
上のリンク先を見るとコマンドライン引数が以下のように書かれています。
$ example_dnn_object_detection --config=[PATH-TO-DARKNET]/cfg/yolo.cfg --model=[PATH-TO-DARKNET]/yolo.weights --classes=object_detection_classes_pascal_voc.txt --width=416 --height=416 --scale=0.00392 --input=[PATH-TO-IMAGE-OR-VIDEO-FILE] --rgb
つまり「yolo.cfg」、「yolo.weights」、「object_detection_classes_pascal_voc.txt」が必要になりますが、これらをどこから取ってきたらいいのかを調べるのに実は一番時間がかかりました。
今回は最新版であるYOLO v7を試してみたいと思いますので、以下のリンクから取得し、適当にファイル名を合わせました。
- yolo.cfg:https://github.com/AlexeyAB/darknet/blob/master/cfg/yolov7.cfg
- yolo.weights:https://github.com/WongKinYiu/yolov7/releases
- object_detection_classes_pascal_voc.txt:https://github.com/pjreddie/darknet/blob/master/data/coco.names
適切な場所に用意したファイルを配置し、先ほどのコマンドを参考に実行すれば難なく動くかと思います。
下の映像は、NHKクリエイティブ・ライブラリーで公開されている素材に対して物体検出を動かしてみた結果です。
閾値0.5のままですが、なかなかいい感じに検出できています。
Haar-Like特徴量やHOG特徴量等を使って人検出していたころは、サンプルコードと一緒に公開されている画像・映像以外で動かしてみるとイマイチな結果になることが多かったのですが、適当に選んだ映像でこれだけ精度良く検出できるのは素晴らしいですね。
セラ/ATF、メーターケーブルの交換
うちのセラは、そこまで状態は悪くないものの、一般的なユーザーがメンテナンスしないところ(ディーラーに任せていれば済むような各種点検・整備以外の部分と言えば伝わるでしょうか)に関しては手を入れていない雰囲気を感じる個体です。
そのため、ATF(オートマオイル)の交換はしていないだろうなぁと思い、今回ネッツトヨタさんに交換対応を依頼しました。
長期未交換のATFを上から循環交換してしまうと、スラッジを巻き上げることによる故障のリスクが無視できないので、今回は下抜きでの交換としました。
まず、ドレーンボルトを外してオイルを抜き、続けてオイルパンとオイルストレーナーを外します。
|
|
排出されたオイルは一度も交換していないor交換してから結構な年数が経過していると思える汚れ方でした。
ちなみに外したオイルパンと洗浄後のオイルパンを並べるとこんな感じです。
磁石は新品なのでめちゃくちゃキレイです。
そして、取外したオイルストレーナーと新品のオイルストレーナーを並べるとこんな感じ。
実はオイルストレーナー(品番:35330-12020)は既にメーカー在庫なしとのことだったので、自分で調達しました。
メーカー在庫がないのにモノタロウで買えるのってなんでなんでしょうね…
なお、ガスケットはトヨタにも在庫があるとのことでしたが、オイルストレーナーを買ったら普通にガスケットも付いてました。
あとは元通りオイルストレーナーとオイルパンを取り付けてATFを入れておしまいです。
ここまでのATF交換における整備代金は2万5千円(うち技術料が1万円)でした。
セラのATF容量は7.2L、使用したATFはちょっとお高いカストロールのです。
安く抑えたい方は安価なATFを選択したり、工賃の安いところを探すのもありかと思います。
そして、旧車あるあるだとは思いますが、メーターの針がプルプル振れてたので、メーターケーブルの交換もしてもらいました。
これまた純正ケーブル(品番:83710-18030、83710-32130)が廃盤なので、スターレットのケーブル(品番:83710-16270)を持ち込みで対応してもらいました。
こちらの整備代金は1万円(部品代なし)でした。