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というように書くと、ライブラリフォルダを認識するようです。

Qtではじめてのアプリをつくった。

最近はAizu Online Judgeでアルゴリズムの問題はやってましたが、 Qtの使い方の勉強で成果物が全然作ることができず、ブログの更新も全然できませんでした。C++やQtの初歩的なレベルのことは一通りやったので、このへんでなにか作ってみようと思い、Qtでアプリを作りました。

アプリといったも全く大したこともなく役に立つものではありませんが、自分の理解力を高めるためにアップします。

QLineEditで入力した数値をビットフィールドで作ったBits構造体にポインタで渡して、各ボタンのランプが点灯するようにしました。また、各ボタンを押したときには、Bits構造体を反転させるようにしています。

Bits構造体は下記の通り。

struct Bits
{
    int bit0:1;
    int bit1:1;
    int bit2:1;
    int bit3:1;
    int bit4:1;
    int bit5:1;
    int bit6:1;
    int bit7:1;
    int bit8:1;
    int bit9:1;
    int bit10:1;
    int bit11:1;
    int bit12:1;
    int bit13:1;
    int bit14:1;
    int bit15:1;
};

ポインタをキャストしてデータを参照しています。

Bits* bits; // Bits オブジェクト
int data; // 入力データ

data = ui->lineEdit_code->text().toInt();
bits = reinterpret_cast<struct Bits *>(&amp;data);

ボタンを押したときに、 bitを反転させます。ポインタで参照すしているのでbitsを変更すればdataの値も変わります。ボタンをおしたら、QLineEditとボタンに表示します。

void MainWindow::on_pushButton_b0_clicked()
{
    bits->bit0 = ~bits->bit0;
    setLineData();
    displayButtons();
}

https://github.com/lingmujianshi/QBitDisplay