2011-12-07 77 views
5

我想要計算OpenCV二進制圖像中的所有白色像素。我當前的代碼如下:在opencv二進制圖像中計數'白色'像素(高效)

whitePixels = 0; 
    for (int i = 0; i < height; ++i) 
    for (int j = 0; j < width; ++j) 
     if (binary.at<int>(i, j) != 0) 
     ++whitePixels; 

然而,使用gprof我發現這是一個非常緩慢的一段代碼,並在節目中大瓶頸剖析之後。

是否有一種方法可以更快地計算相同的值?

+0

你試過改變高度和寬度嗎?我的意思是循環寬度和高度?這可能會改善循環,取決於如何將圖像放在內存中。 –

+2

您可以直接通過()函數訪問圖像數據嗎? – jrok

+0

做jrok建議可能會更快。我想知道[這個常見問題解答條目](http://opencv.willowgarage.com/wiki/faq#How_to_access_image_pixels)是否相關。 – Brian

回答

20

cvCountNonZero。通常,任務的OpenCV實現經過了大量優化。

(C代碼)
+3

@karlphillip你的意思是['cv :: countNonZero'](http://opencv.willowgarage.com/documentation/cpp/core_operations_on_arrays.html#cv-countnonzero)? –

+0

完美的,一個優化的內置功能。正是我在找的東西。 –

+0

添加當前文檔鏈接以回答(可以在將來更新,不像此評論)。 – handle

0

您可以使用並列計算。你將圖像分成N部分並在不同的線程中運行你的代碼,然後你得到每個線程的結果,然後你可以添加這個結果來獲得最終的數量。

+1

比爾的算法如果正確實施,可能應該是內存綁定而不是CPU綁定。在普通桌面計算機上,通常並行化對於內存限制任務沒有幫助。 – Brian

-2

行中的最後一個像素之後通常是第一像素的下一行:

limit=width*height; 
i=0; 
while (i<limit) 
{ 
    if (binary.at<int>(0,i) != 0) ++whitePixels; 
    ++i; 
} 
+0

或者將它作爲一個滑動指針來實現,它將消除索引。 –

+0

和/或在[i]和[i + 1]上一次測試兩個,並將索引/指針加2。這將使所需的循環減半。 –

+0

應使用isContinuous()對矩陣進行連續性測試。如果矩陣不連續,則此方法將失敗。 –

-2

其實binary.at<int>(i, j)是上網速度慢!

下面是訪問速度比您快的簡單代碼。

for (int i = 0; i < height; ++i) 
{ 
uchar * pixel = image.ptr<uchar>(i); 
    for (int j = 0; j < width; ++j) 
{ 
    if(pixel[j]!=0) 
    { 
     //do your job 
    } 
} 
} 
相關問題