Qt6.7.2とOpenCV4.10をコラボするのに苦労した記録
今回の記事はこれです。
本当に苦労しました。多分丸1日使っちゃった。
まず、私の環境ですが、
Windows 11 64bit
QtCreator 14.0
Qt 6.7.2
OpenCV 14.0
コンパイラは、MinGW 64bit
です。
途中いろいろと紆余曲折あったので、全てを一本の筋道をつけて語るのは難しいんですけど、覚えている限り書いておきたいと思います。
まず、OpenCVをQtで使おうとして、opencvのソースコードをダウンロードして展開しました。ダウンロードフォルダにおいたままだと具合が悪いので、CドライブにOpenCVというフォルダを作り、その中に入れました。
opencvは、buildというディレクトリとsourcesというディレクトリを持ちます。
そして、この状態で、
find_package(OpenCV REQUIRED)
target_link_libraries(ImageEditor PRIVATE ${OpenCV_LIBS} Qt${QT_VERSION_MAJOR}::Widgets)
とかを書けば、OpenCVとコラボできるようになりますよって、いろいろな所に書いてあるんですよ。でも、私の場合はエラーばっかり起きるんですよね。
どんなエラーかというと、Mat関数とかが未定義だっていうエラー。
undefined reference to cv::Mat::Mat(int, int, int, void*, unsigned long long)'
こういうのが13個くらいでます。
opencvというライブラリは存在し、そのパッケージも見つけることができているのに、どうしてこんなことになるのか・・・。もちろん、パスも通しています。
これは、一つの大きな原因として、OpenCV側のビルド、コンパイルがMinGWでは行われていないことがあげられます。Qtのコンパイルと、OpenCVのコンパイルが一致していないと、うまくいかないようなのです。
そこで、build-mingwというフォルダをOpenCVフォルダに作り、このディレクトリへ移動します。そして、この命令を使いました。
cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release C:/OpenCV/opencv/sources
昨日の記事ではOpenCVとQtのコラボで、Ninjaが必要と書いたのですが、それだとうまくいきませんでした。MinGW Makefilesだと、MinGW用にビルドできるのです。
しかし、結果はこんな感じ。
-- The CXX compiler identification is MSVC 19.34.31937.0
-- The C compiler identification is MSVC 19.34.31937.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/14.34.31933/bin/Hostx86/x86/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/14.34.31933/bin/Hostx86/x86/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- ocv_init_download: OpenCV source tree is not fetched as git repository. 3rdparty resources will be downloaded from github.com by default.
こうやってスタートする。よく見ると、MSVCでコンパイルが行われている。なぜ?MinGW MakeFilesでビルドシステムを指定したのに・・・。
というわけで、コンパイラが何らかの理由で強制的にMSVCになっているようだから、
cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=C:/mingw64/bin/gcc.exe -DCMAKE_CXX_COMPILER=C:/mingw64/bin/g++.exe C:/OpenCV/opencv/source
これで、g++.exeを強制的に指定して、これでビルド。すると、
cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=C:/mingw64/bin/gcc.exe -DCMAKE_CXX_COMPILER=C:/mingw64/bin/g++.exe C:/OpenCV/opencv/source
これで直接指定してやればOKでした。これでOKだった。何度やっても、MSVC。環境変数でminGWを上に優先させてもMSVCが使われるので、ハマりました。
前提として、MinGWをインストールしておくことが重要になる。
それはここを参考に
で、出来上がったファイルのlibフォルダを調べてみると、何と空っぽ!(最初の階層のlibフォルダです。)
binファイルにも、exe系のファイルは一つもない状態だった。
もう一手必要だったのです。
c:\OpenCV\opencv\build-mingw>cmake --build . --target install
これを打つ、すると、
[ 0%] Built target opencv_dnn_plugins
[ 0%] Built target opencv_highgui_plugins
[ 0%] Building C object 3rdparty/libjpeg-turbo/CMakeFiles/jpeg12-static.dir/src/jcapistd.c.obj
[ 0%] Building C object 3rdparty/libjpeg-turbo/CMakeFiles/jpeg12-static.dir/src/jccolor.c.obj
[ 0%] Building C object 3rdparty/libjpeg-turbo/CMakeFiles/jpeg12-static.dir/src/jcdiffct.c.obj
[ 0%] Building C object 3rdparty/libjpeg-turbo/CMakeFiles/jpeg12-static.dir/src/jclossls.c.obj
[ 0%] Building C object 3rdparty/libjpeg-turbo/CMakeFiles/jpeg12-static.dir/src/jcmainct.c.obj
[ 0%] Building C object 3rdparty/libjpeg-turbo/CMakeFiles/jpeg12-static.dir/src/jcprepct.c.obj
[ 0%] Building C object 3rdparty/libjpeg-turbo/CMakeFiles/jpeg12-static.dir/src/jcsample.c.obj
こんな感じで、0%から100%までコンパイルが始まる。これが多分1時間くらいかかった。
これが終わって、libファイルの中身を見ると、ちゃんとlibファイルの中にいくつかのデータが入っているのがわかる。
しかし、目指すのは、こちらのlibファイルではない。
install/x64/libの方だ。
つまり、OpenCVConfig.cmakeが入っているフォルダが重要なのだという。
(だが、installフォルダにも、OpenCVConfig.cmakeフォルダは存在する。こちらを指定するとうまくいかない。同じ名前のファイルがいくつも存在しているようで、これもさらに混乱を加速させた要因だった。)
# OpenCVConfig.cmakeがあるディレクトリ
set(OpenCV_DIR "C:/OpenCV/opencv/build-mingw/install/x64/mingw/lib")
find_package(OpenCV REQUIRED)
target_link_libraries(ImageEditor PRIVATE ${OpenCV_LIBS} Qt${QT_VERSION_MAJOR}::Widgets)
この3つを、QtプロジェクトのCMakeLists.txtに書き込む。
すると・・・。
こうなる。
このアプリは、
を参考にして書いたもの。そして、OpenCVの力はちゃんと発揮されているだろうか。
Blurボタンを押すと、ちゃんとモザイク処理がかかるようになる。
これでQtとOpenCVのコラボがQt6と、最新のOpenCV4.10で成功を見た。
元ネタはQt5だから、読み進めるのが非常に困難です。