Qt5とOpenCV4を使ったアプリを作りたい

タイトルにある通り、Qt5とOpenCV4を使ったアプリを作りたいのですが、なかなか思うように進んでいません。両方とも初心者なので入門書から勉強しているところです。ここ2・3ヶ月はOpenCV4基本プログラミングと本で勉強していました。Qt5はYoutubeのチュートリアル動画を使って勉強しています。

一通り勉強してなんとなくわかってきたので、試しにアプリを作ってみました。OpenCVのVideoCaptureで動画を取り込んで、手動でカーソルを合わせるアプリ。顕微鏡にカメラを取り付けて、表示することを想定しています。更新速度が遅かったり、クラッシュしたりと本当に使い物になりませんが、作成するにあたってわかったことを忘備録として書きます。

Qt GUIでは標準ライブラリのスレッドが使えない

ボタンを押して、VideoCaptureを開始し、動画を連続で表示させようとしたら他の操作ができません。スレッドの出番です。標準ライブラリにtreadがあるので、実装して実行したらクラッシュ。わけがわかりませんが、ネットで色々調べると、Qt で使えないとのこと。領域が被る?まだよく理解できてませんが、QThreadを使って実装することができました。

connectには書き方が2種類ある

Qtではsignal、slot、connectでイベントを設定しますが、参考するサイトによって書き方がかなり違うので戸惑ってしまします。下記の2つの書き方があるようです。

①connect(mThread,SIGNAL(NumberChanged(int)),this,SLOT(onNumberChanged(int)));

②connect(mThread, &MyThread::NumberChanged, this, &Dialog::onNumberChanged);

基本は connect(送り元オブジェクト, 送り元の関数, 送り先オブジェクト, 送り先の関数)の関数です。

①はSIGNALやSLOTという命令を使っています。引数は(int)のよう型だけを書くのがポイント。②はクラス名から書き、引数は書きません。

OpenCV4のMatからQt5のQImageへ変換

ネット上に乗っているOpenCVの情報はまだまだ古いものがあり、そのままでは今のバージョンでエラーになることがあります。OpenCVはBGR、QtはRGBの色配列の並びが違うので変換する必要があります。OpenCVで色を変換する場合はcvtColorで色を入れ替えますが、その引数で書かれているCV_BGR2GRAYはCOLOR_BGR2RGBとしなければなりません。QImageに変換するにプログラムは下記の通り。

video >> frame;
        cv::cvtColor(frame,frame,cv::COLOR_BGR2RGB);
        QImage qimgin (frame.data,
                    frame.cols,
                    frame.rows,
                    static_cast<int>(frame.step),
                    QImage::Format_RGB888);

今後

今回のアプリでは動画の更新が1秒間隔になってます。連続にするとクラッシュしてしまうからです。また、カーソルと連続で移動すると同じくクラッシュしてしまします。使い物になりません。まだまだ、QtやOpenCVを使えているというレベルになっていないので、もう少しサンプルを見ながら勉強して出直すつもりです。とりあえずソースはアップしました。

https://github.com/lingmujianshi/CursorGenerator

Qt5 OpenCV4 ライブラリ設定

Qt5 でOpenCV4を使用するときにライブラリの読み込みができなく結構苦労したのでめも書き

 環境
macOS Mojave 10.14
Qt Creator 4.9
Desktop Qt5.12.3 clang 64bit
opencv-4.1.0

pmakeの .proファイルに下記のように記載する

INCLUDEPATH += /usr/local/include/opencv4
QMAKE_LFLAGS +=  -L/usr/local/lib
LIBS += -lopencv_calib3d -lopencv_core -lopencv_dnn -lopencv_features2d -lopencv_flann -lopencv_gapi -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_video -lopencv_videoio

参考にサイトでは下記の感じでできるようです。。(参考はUbuntuでやっていたのでmacとは違う?)

LIBS += `pkg-config opencv4 --cflags --libs`

私の環境ではLIBS += -L/usr/local/lib が受け付けてくれませんでした。QMAKE_LFLAGS += -L/usr/local/libというように書くと、ライブラリフォルダを認識するようです。

OpenCVのサンプルをやるだけで苦労した

将来的にOpenCVを使ってソフトを作るつもりなので、インストールしてサンプルファイルを駆動させようと思ったら、意外と苦労しました。C++でサンプルを動作させるだけなら、何年か前にもやったことがあるのですが、改めてやってみたらできませんでした。

環境

マシン macOS Mojave 10.14.

言語 C++

ライブラリ OpenCV 4.1.0

コンパイラ Clang / LLVM

実行するとどうしても、リンク異常が出てしてしまいます。参考は下記のURLです。

OpenCV/C++で画像処理入門 vol.1 〜画像を表示してみよう〜

ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

ソースからコンパイルして、cmakeを使って実行すると問題なくできました。

C++のOpenCVをCMakeで使う

いろいろ調べた結果、リンカエラーが発生するときは、ライブラリがきちんと割り当てられていなかったということ。pkg-configの設定ファイルが悪かったみたいです。余計なlibファイルも記載されていました。/usr/local/libフォルダからopencvに関連するのファイルを抽出し書き直しましたファイルはこちら。

opencv4.pc

prefix=/usr/local
exec_prefix=${prefix}
includedir=${prefix}/include
libdir=${exec_prefix}/lib

Name: opencv4
Description: The opencv library
Version: 4.0.0
Cflags: -I${includedir}/opencv4
Libs: -L${libdir} -lopencv_calib3d -lopencv_core -lopencv_dnn -lopencv_features2d -lopencv_flann -lopencv_gapi -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_video -lopencv_videoio

pkg-configを実行すると

$ pkg-config opencv4 --cflags --libs
-I/usr/local/include/opencv4 -L/usr/local/lib -lopencv_calib3d -lopencv_core -lopencv_dnn -lopencv_features2d -lopencv_flann -lopencv_gapi -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_video -lopencv_videoio

コンパイルと実行は下記のようにやる。ちなみにstd=c++11を指定しないとコンパイルができません。

$ clang++ -std=c++14 $(pkg-config --cflags --libs opencv4) main.cpp
$ ./a.out