2013-06-04 25 views
7

Jaki jest najszybszy sposób na uzyskanie liczby białych pikseli na obrazie binarnym za pomocą OpenCV? Czy jest coś szybszego niż użycie dwóch pętli i uzyskanie dostępu do obrazu piksel po pikselu?Najszybszy sposób na uzyskanie liczby białych pikseli w obrazie binarnym za pomocą OpenCV

+0

Czy obraz jest w rzeczywistej skali szarości, czy jest to obraz binarny? – Aurelius

+0

@Aurelius: To jest właściwie obraz binarny, powinienem był to napisać w pytaniu. – xx77aBs

Odpowiedz

11

najbardziej zwięzły sposób do osiągnięcia tego celu jest:

cv::Mat image, mask; //image is CV_8UC1 
cv::inRange(image, 255, 255, mask); 
int count = cv::countNonZero(mask); 

Jeśli pracujesz na obrazie binarnym, a następnie wezwanie do cv::inRange() jest niepotrzebny, a po prostu cv::countNonZero() wystarczy.

Mimo że dowolna metoda musi powtarzać się przez wszystkie piksele, może być w stanie wykorzystać wbudowane w OpenCV parallel_for_(), co pozwala na równoległe wykonanie.

Jeśli obraz jest ciągły, można przeglądać wszystkie dane za pomocą pojedynczej pętli.

+0

Dzięki, cv :: inRange jest tym, co chciałem! Używam OpenCV przez wrapper EmguCV (w C#), a ta jedna linia przyspieszyła mój program o około 40%. Czy masz pojęcie, dlaczego pętla na dwie pętle jest wolniejsza? – xx77aBs

+3

Nie jestem zaznajomiony z C#, ale uważam, że sprawdza granice, gdy wykonujesz iterację w pętli, co może wyjaśnić niektóre różnice w wydajności. – Aurelius

+0

Dzięki, sprawdzanie granic naprawdę spowalnia rzeczy. Ale zdarzenie po wyłączeniu sprawdzania ograniczeń, dla bardzo dużego obrazu (10240x7680) funkcja CV trwa około 70ms, a dwie dla pętli około 350ms. Po użyciu Parallel.For, obie pętle trwały około 200ms, ale to znacznie dłużej niż implementacja OpenCV. – xx77aBs