2012-04-26 14 views
8

opencvとQtを使ってアプリケーションを作成しています。アプリケーションの中で私はビデオを録画するための小さなツールを作成しています。このため、メインイベントスレッドをブロックしないように、私は記録スレッドを含む別のダイアログを作成しました。私はこのカメラの出力を見たいと思っていました(私は録音コードをまだ紹介していません)。だから私はQThreadをサブクラス化し、run()機能は以下の通りです:OpenCVとQt VideoCaptureでウィンドウ上の正しいカメラが開けない

void VideoRecordThread::run(){ 
    cv::VideoCapture capture; 
    cv::Mat frame; 
    QImage img; 

    qDebug() << "Opening camera" << cameraIndex ; 
    capture.open(cameraIndex); 

    if(!capture.isOpened()){ 
     qDebug() << "Could not open camera" << cameraIndex; 
     emit threadReturned(); 
     return; 
    } 

    while(!stopFlag){ 
     capture >> frame; 
     qDebug() << "Frame Width = " << frame.cols << "Frame Height = " << frame.rows; 
     if(frame.cols ==0 || frame.rows==0){ 
      qDebug() << "Invalid frame skipping"; 
      continue; 
     } 
     img = cvMatToQImage(frame); //Custom function 
     emit imageCaptured(img); 
    } 
    capture.release(); 
    emit threadReturned(); //Custom signal 
    qDebug() << "Thread returning"; 
} 

これが動作するようになったが、問題は選択するように私を求めスレッドが開始したとき、私は「青のうち、」新しいダイアログを得るということですカメラが接続されているカメラの1つを選択すると、時々動作し、ときどき動作しない場合があります。ここで私が得るダイアログは次のとおりです。

enter image description here

私が何ができるか上の任意のヘルプ?

+0

「cameraIndex」の値は? – karlphillip

+0

cameraIndexが0 – msmechanized

+0

カメラが1台しかない場合、またはカメラが使用されているかどうかは関係ありません。-1を渡すことができます。 Windowsでは、ユーザーがビデオソースを選択するために、インデックス0がそのダイアログを開きます。 – karlphillip

答えて

4

OpenCVには、メインスレッドから実行されていない機能がある場合に問題があることがわかりました。

キャプチャプロシージャの初期化をアプリケーションのメインスレッドに移動し、残りをセカンダリスレッド上に残します。初期化部分は次のようになります:

+0

ええ、問題は、私はメインウィンドウ - >録画ダイアログ - >ビデオ録画スレッドだということです。 VideoCaptureをスレッド2レベルからメインウィンドウに移動するにはどうすればよいですか? – msmechanized

+0

クラス間で 'cv :: VideoCapture'オブジェクトを渡すだけです。必要に応じてクラスのコンストラクタを配置することができます。新しいクラスが初期化されると、すでにキャプチャインターフェイスにアクセスできます。また、メインスレッドで正常に初期化された後、これらのクラスにこの変数を設定する新しいメソッドを追加します。または、最後の(醜い)オプションとして、グローバル変数として 'cv :: VideoCapture capture'を宣言してください - 私はテスト目的のために、実装とテストがより速くなると思います。 – karlphillip