2013-05-13 21 views
0

所以,我一直在用opencv開發一個實時跟蹤系統。幾天前,我不得不開始使用directshow(這對我來說是全新的),因爲我需要從網絡攝像頭獲得更高的分辨率。分辨率越高,CPU使用率越高。當僅使用directshow而沒有使用任何opencv算法時,cpu運行在50%。 (我有雙核心= 100%使用一個核心)多核,使從內部函數調用的函數在第二個核上運行。 directshow,opencv

所以現在我需要擴展這個系統,以便使用我的兩個核心。

我發現從微軟這個很好的例子,並能夠運行它,用我的兩個核心:

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

這完美運行,並且我能使用約85%的總CPU(帶剛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被每幀(或者以每秒至少多幀,幀可能會使用這個時候錯過?!)

我的想法是讓「sampleCallBackFunction()」在第二個內核上運行(我不想將其鎖定到特定內核,只使用第一個可用的)

但這個例子,我發現開始兩者的功能同一時間,從同一個地方。是否有可能以某種方式告訴系統「sampleCallBackFucntion」應該在另一個核心上運行?

我的另一個想法是將數據存儲在「sampleCallBackFunction()」中,並且還將bool「newFrameAvailable」設置爲true。讓另一個線程從全局數組中提取數據。

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

所以。我的問題:如何從另一個函數內調用函數(「sampleCallBackFunction」從「startDirectshow」調用)?

謝謝!

回答

1

你的問題不太清楚,但我想你想在另一個線程中調用sampleCallbackFunction。 (函數通常在另一個函數內調用,這會使調用堆棧...)

由於DirectShow,您的sampleCallBackFunction已經最有可能運行在與主線程不同的流線程上。當然,流線程上發生的所有事情都是一個邏輯核心的負擔。

然後,如果您在sampleCallbackFunction上創建另一個線程,那麼您的系統足夠聰明,可以在可用內核上分配工作,這不是問題。但我懷疑parallel_invoke是否可以讓你靈活地做你必須做的事情,如果你真的想在那裏做另一名工人,我建議你找CreateThread

順便說一句:在GUI應用程序中,調用另一個線程中函數的最簡單方法是使用SendMessage,因爲調用總是分發給創建該窗口的線程。儘管如此,這個呼叫仍在阻止......

+0

感謝您的回答。你是對的,我想爲samplerCallbackFunction創建一個使用另一個cpu-core的新線程。但我想知道,如果我的系統應該通過可用內核分配負載,爲什麼我無法將CPU使用率提高到50%以上?第二個核心運行的是~4%,而我的軟件需要moooore cpu power:D(我的視頻輸出很差) – Easyrider 2013-05-13 12:33:54

+1

要利用資源,必須先創建工作線程。在這種情況下,您的主線程(大部分)處於空閒狀態(僅管理過濾器圖),而流線程正在從相機中獲取幀。單線程不能使用多於一個邏輯核心。 – Vaaksiainen 2013-05-13 12:39:12

+0

我看了一下「資源監視器」,發現我的軟件有7個線程處於活動狀態。而且我也看到有幾次它使用了52%的CPU。這意味着一切都已經在多核上運行,我不需要關心這個?! – Easyrider 2013-05-13 13:02:34

1

首先,你可能想要更好地檢查什麼是CPU過熱50%,沒有處理。最有可能的是,通過在另一個像素格式域中處理視頻,您可以避免轉換爲RGB色彩空間。裸視頻捕捉不需要那麼高的CPU使用率值。

如何從另一個函數內調用函數(「sampleCallBackFunction」從「startDirectshow」調用)?

如果您想要並行處理和/或在處理數據時繼續捕獲,這並不是您想要做的。 startDirectshow線程是一個控制線程,它啓動/停止處理並啓動內部流線程。與控制線程同步將不會提高性能,但會帶來(a)同步費用的麻煩,以及(b)終止死鎖的可能性。

如果您想要並行處理,您需要在採樣器回調中複製數據並儘快退出回調。然後,線程池(如TPL或您自己的線程)將異步處理,而不影響捕獲性能。

+0

對不起,但我認爲目前這對我來說有點複雜。使用任務並行庫。你有沒有像我的第二個替代方案我問題?我想我需要閱讀這個。 – Easyrider 2013-05-13 13:30:55

+0

關於CPU過熱。我在1.3GHz,3GBram,64bit筆記本電腦上運行。而且已經有幾年了。用一個可憐的圖形卡。我將輸入通過samplegrabber轉換爲RGB。難道這就是爲什麼我的CPU達到50%?我正在做這個直接的東西來獲取數據到我的opencv軟件。你知道是否有比rgb更好的色彩空間來轉換?謝謝! – Easyrider 2013-05-15 11:31:30

+0

我不太在意TPL/async是如何工作的。我是否應該創建另一個從堆棧中提取數據的任務,如果它是空的,它只是等待直到有一個框架可用? (就像我的問題中的第三個代碼塊?)我可以在谷歌上搜索什麼來查找關於此的更多信息?謝謝! – Easyrider 2013-05-15 11:53:54