0

それで、私はopencvを使ったリアルタイム追跡システムに取り組んできました。数日前、ウェブカメラの解像度を高くする必要があったため、directshow の使用を開始する必要がありました (これは私にとってまったく新しいものでした)。解像度が高くなると、CPU 使用率が高くなります。opencvアルゴリズムなしでdirectshowのみを使用すると、CPUは50%で実行されます。(私はデュアルコアを持っています= 1つのコアの100%の使用率)

そのため、このシステムを拡張して、両方のコアを使用する必要があります。

私はマイクロソフトからこの素晴らしい例を見つけ、両方のコアを使用して実行できました:

void test1(){
    parallel_invoke(
        []() { run1(); },
        []() { run2(); }
    );
}

これは完全に実行され、合計 CPU の約 85% を使用できます (ループと機能を備えた 2 つの関数のみ)。これを他のシステムで使用したいと考えています。そして、私はそれを行う方法がわかりません。

私のシステムの簡単な説明:

int main(){
     startDirectshow()
};

startDirectShow(){
     //code for creating the directshow filter graph. including iSampleGrabber filter.
}

sampleCallBackFunction(....){
      // function called for every frame in the graph
}

これまでのところすべてが機能しています。sampleCB はフレームごとに呼び出されます (または、少なくとも 1 秒あたり複数のフレーム、これを使用するとフレームが失われる可能性があります?!)

私の考えは、「sampleCallBackFunction()」を 2 番目のコアで実行することでした (特定のコアにロックしたくありません。使用可能な最初のもののみを使用します)。

しかし、私が見つけた例では、同じ場所から両方の機能を同時に開始しています。何らかの方法で、「sampleCallBackFucntion」を別のコアで実行する必要があることをシステムに伝えることは可能ですか?

私が持っていた別のアイデアは、データを「sampleCallBackFunction()」に保存し、ブール「newFrameAvailable」をtrueに設定することでした。そして、別のスレッドがグローバル配列からデータを取得できるようにします。

while(true)
    If (newFrameAvailable){
         get-next-frame-in-buffer-and-do-opencv-algorithm();
    }
    else{
         do-nothing();
    }
}

そう。私の質問: 別の関数内から呼び出される関数を作成する方法 (「sampleCallBackFunction」は「startDirectshow」から呼び出されます)?

ありがとう!

4

2 に答える 2

1

まず、処理なしで CPU を最大 50% 過熱させている原因を正確に確認することをお勧めします。ほとんどの場合、ビデオを別のピクセル形式ドメインで処理することで避けることができる RGB 色空間への変換です。ベア ビデオ キャプチャでは、それほど高い CPU 使用率の値は必要ありません。

別の関数内から呼び出される関数を作成するにはどうすればよいですか (「sampleCallBackFunction」は「startDirectshow」から呼び出されます)。

これは、並行して処理したり、データの処理中にキャプチャを続けたりしたい場合に、実際にやりたいことではありません。スレッドは、startDirectshow処理を開始/停止し、内部ストリーミング スレッドも開始する制御スレッドです。制御スレッドと再同期してもパフォーマンスは向上しませんが、(a) 同期のコストと (b) 終了デッドロックの可能性という頭痛の種になります。

並行して処理したい場合は、サンプル グラバー コールバックでデータをコピーし、できるだけ早くコールバックを終了する必要があります。次に、 や独自のスレッドのプールが、TPLキャプチャのパフォーマンスに影響を与えることなく非同期で処理を行います。

于 2013-05-13T13:11:34.867 に答える