2011-12-07 2 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

이 at() 함수 대신 직접 이미지 데이터에 액세스 할 수 있습니까? – jrok

+0

jrok 제안을하는 것이 아마 더 빠를 것입니다. 나는 [이 FAQ 항목] (http://opencv.willowgarage.com/wiki/faq#How_to_access_image_pixels)이 관련이 있는지 궁금합니다. – Brian

답변

20

cvCountNonZero. 일반적으로 작업의 OpenCV 구현은 크게 최적화됩니다.

행의 마지막 픽셀이 보통 다음 행의 첫 번째 픽셀 뒤에
+3

@karlphillip 당신은 ['cv :: countNonZero']를 의미합니까 (http://opencv.willowgarage.com/documentation/cpp/core_operations_on_arrays.html#cv-countnonzero)? –

+0

완벽하고 최적화 된 내장 기능. 내가 뭘 찾고 있었는지. –

+0

대답에 대한 현재 의사 링크가 추가되었습니다 (이 설명과 달리 향후 업데이트 될 수 있음). – handle

0

평행선 계산을 사용할 수 있습니다. 이미지를 N 부분으로 나누고 서로 다른 스레드에서 코드를 실행 한 다음 각 스레드의 결과를 얻은 다음이 결과를 추가하여 최종적으로 얻을 수 있습니다.

+1

Bill의 알고리즘은 올바르게 구현 된 경우 CPU 바인딩보다 메모리 바인딩되어야합니다. 일반 데스크탑 컴퓨터에서 일반적으로 병렬 처리는 메모리 바인딩 작업에 도움이되지 않습니다. – Brian

-2

(C 코드)

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 
    } 
} 
} 
관련 문제