下記ネタの続き、QtからOpenCVのVideoCaptureを使う時の忘備録あれこれ。
CMake.txtにOpenCV関係の記述追加
CMake.txtより下記抜粋、先頭4行と最終行がOpenCV関係の設定です。
# # for OpenCV set(OpenCV_DIR E:\\Software\\opencv_mingw) find_package(OpenCV REQUIRED) set(CMAKE_PREFIX_PATH ${OpenCV_DIR}) INCLUDE_DIRECTORIES( ${OpenCV_INCLUDE_DIRS} ) target_link_libraries(TegeViewer PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) target_link_libraries(TegeViewer PRIVATE ${OpenCV_LIBRARIES})
注意、TegeViewerはMinGWでコンパイルしているので、
OpenCVもMinGWでビルドしたものが必要です。
今回は手っ取り早く、下記から頂きました。(ビルド済みのもの)
VideoCaptureの検出
VideoCapture関係は、CvVideoCaptureクラスにまとめ、
それをカメラコントロールのダイアログから参照します。
InitOpenCvCaptureで、indexを変えてcapture.openを実行し、
戻り値がtrueのindexをVectorとして返します。
(indexが飛ぶ場合も有るそうなので、Vectorで返します)
MAX_CAPTUREは最大接続台数で、現状"5"にしています、
もっと増やせますが、検出時間は長くなるはず。
QVector<int> CvVideoCapture::InitOpenCVCaptute() { QVector<int> vResult; if(capture.isOpened()) capture.release(); videoCaptureCount = 0; for (int i = 0; i < MAX_CAPTURE; ++i) { bool result = capture.open(i, cv::CAP_ANY); if (result) { videoCaptureCount++; vResult.append(i); } } return vResult; }
VideoCapture Propertyの取得
ダイアログの"Get Property"ボタンでプロパティを取得します、
下記のCAP_PROP_POS_MSEC ~CAP_PROP_AUTOFOCUSまで、計40個
他にもProperty有りますが、上記は0~39と連番なので抜粋し、
QStringのVectorで”CAP_PROPERTY”という40個の項目名を定義、
下記で順番に読み込み、文字列でダイアログに表示させてるだけです。
QString CvVideoCapture::GetAllProperty() { QString propText = ""; if (capture.isOpened()) { for (int i = 0; i < CAP_PROPERTY.size(); ++i) propText += CAP_PROPERTY[i] + " : " + QString::number(capture.get(i)) + "\n"; } propText = propText.trimmed(); return propText; }
後で気付いたのですが、cv::VideoCapture::get(int propId) の戻り値が0の場合、
そのPropertyは未対応みたいです、ということは、設定値で"0"は無いってことかな?
VideoCapture Propertyの設定
cv::VideoCapture::set(int propId, double value)を呼んでるだけです。
CODEC(cv::CAP_PROP_FOURCC)だけ、4文字を分割します、
例えば"MJPG"だとcv::VideoWriter::fourcc('M', 'J', 'P', 'G')と設定します。
bool CvVideoCapture::SetCodec(QString format) { std::string sVal = format.toStdString(); const char* pCodec = sVal.c_str(); bool result = capture.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc(pCodec[0], pCodec[1] , pCodec[2], pCodec[3])); return result; }
パラメータ設定ダイアログ
WIndows版のOpenCVでは、cv::CAP_PROP_SETTINGSに"1"を書くと、
下記のダイアログが表示され、パラメータ変更出来ます、これ便利。

例えば明るさ、コントラストは、BRIGHTENESS、CONTRASTに相当
画像取込
CvVideoCaptureクラスは、QtのQThreadクラスを継承させています、
親はMainWindowで、Start(▶)ボタンでThread開始(Thread→start())
CvVideoCaptureのrun()内で、画像を取込み毎にBGR→RGBに変換し、
updateCapture()のsignalを発生させます。
void CvVideoCapture::run() { QMutex mutex; while(true) { mutex.lock(); if (this->StopVideoCapture) { break; } mutex.unlock(); capture >> frame; cv::cvtColor(frame, dst, cv::COLOR_BGR2RGB); emit updateCapture(); g_pUtil->CalcFrameRate(); } qDebug() << "FPS:" << capture.get(cv::CAP_PROP_FPS); }
MainWindow側では、CvVideoCaptureクラスからMat形式の画像を取得し、
それをQtのQImageに変換してimageScene->SetQImage(qimg)で表示させます。
色々ごちゃごちゃやってるのは、前回とサイズが変わった場合の再設定とか。
cv::Mat matimag;
videoCapture->GetMat(&matimag);
QImage qimg = QImage((const unsigned char*)(matimag.data), matimag.cols, matimag.rows, QImage::Format_RGB888);
bool sizeChanged = imageScene->IsNullImage() || imageScene->GetImageHeight() != qimg.height()
|| imageScene->GetImageWidth() != qimg.width();
if (sizeChanged)
infoDock->ActivateDock(SELTYPE_RECT);
imageScene->SetQImage(qimg);
if (!g_pUtil->IsCameraStarted()) {
this->setCursor(Qt::ArrowCursor);
g_pUtil->SetCameraStatus(true);
pixelFormat = "";
showTitle();
enabler(true);
changeCursorColorAction->setEnabled(true);
if (sizeChanged) {
imageView->resetTransform();
imageView->InitZoomLevel();
imageView->setSceneRect(imageScene->GetImageRect());
fitWindow();
}
}
With / Height /FrameRate
いまいち挙動が判りません、起動直後はFrameRateは常に0になっている、
WidthやHeightも、何回か設定しないと反映されない? or 設定順が有るのか?
TegeViewer内のFramaRate表示も、カメラ設定と合わない場合有り。
良く考えたら、TegeViewerで動画として取り込んでいる訳では無いので、
(Frameごとに単独のMat画像として読む、の繰り返し)
CAP_PROP_FPS は関係無いのかもしれません。
改めてプロパティ見ると、CAP_PROP_FORMAT というプロパティも有りましたね、
なんやかんやで、色々見直すべきところが有りそうです。