2

OpenCV を使用して組み込み Linux コンピューターで実行するために開発しているリアルタイム コンピューター ビジョン プログラムのキャプチャ パフォーマンスを改善しようとしています。複数のスレッドと共有メモリ バッファを使用して、(1) ビデオ フレームのキャプチャと (2) それらの処理 (「生産者/消費者の問題」と思われます) のタスクを分離したいと考えています。pthread、mutex 変数、および条件変数について調べましたが、それらを関数でどのように使用する必要があるかわかりませんselect()

現在、ビデオ フレームは、Video4Linux2 Video Capture Exampleを利用したコードを使用してキャプチャされselect()ます。私が理解しているようにselect()、ウェブカメラからデータが利用可能になるまでプログラムをブロックします。これは遅くなり、時間の大幅な無駄になる可能性があります。できれば、その無駄な CPU サイクルを画像処理に使用したいと考えています。(もちろん、これは常に 1 フレーム分「古くなった」画像に対して処理を行う必要があることを意味しますが、30 fps では実質的にリアルタイムになります)。

とを使用して共有データを保護するサンプル コードをいくつか見つけましたが . より具体的には、私の懸念を説明するための疑似コードを次に示します。(注:これらのスレッドが実際に正しく機能するには、上記のリンクされた例のようなループやその他のチェックを含める必要があることを認識しています。)pthread_mutex_lock()pthread_mutex_control()select()

void* capture()
{
    pthread_mutex_lock(&mutex);             // protect shared data
    pthread_cond_wait(&space_avail,&mutex); // make sure the buffer has room

    ///  capture code... ///

    select(fd+1, &fds, NULL, NULL, &tv);  // waiting for data...
                                          // Want to be processing frames
                                          // during select, but won't the
                                          // processing thread be blocked
                                          // by the mutex lock?

    // store image to the frame buffer

    /// more capture code... ///

    pthread_cond_signal(&data_avail);
    pthread_mutex_unlock(&mutex);
}


void* process()
    pthread_mutex_lock(&mutex);
    pthread_cond_wait(&data_avail);

    // access the most recently stored frame from the buffer

    /// Do image processing ///

    pthread_mutex_signal(&space_avail);
    pthread_mutex_unlock(&mutex);
}
4

1 に答える 1

0

私があなたの質問を正しく理解していれば、あなたのプログラムが選択を待っているときに浪費されているビジーな待機サイクルを避け、それを画像処理に利用したいと考えています。間違っている場合は修正してください。

私の経験では、これを行う簡単な方法は、select API が動作するように小さなタイムアウトを指定することです。Select API は、このタイムアウトを待機します。この間に Web カメラからデータを受信した場合、select からの戻り値はゼロ以外になります。その期間に興味深いものが見られない場合、戻り値は 0 になります。

したがって、疑似コードを次のように変更できます。

void* capture(){
    while(true){//iterate how many times you feel it is valid to
        if (select(fd+1, &fds, NULL, NULL, &tv)!=0){
              //We have found something here.take data from the webcam.
              //break from the loop.
              break;
         }else{
              //timeout occurred. process the image.
         }
     }
     //process the data from the webcam
}

これで問題が解決したかどうかお知らせください。Select API の詳細については、http: //linux.die.net/man/2/selectを参照してください。

于 2013-10-23T23:39:22.633 に答える