Counting black & white pixels with a threshold
I use ROI to work with a part of image that i am interested in, and now i want to count black & white pixels in it. Although something as simple as:
int count_black = 0;
int count_white = 0;
for( int y = 0; y < imgROI.rows; y++ ) {
for( int x = 0; x < imgROI.cols; x++ ) {
if ( imgROI.at<cv::Vec3b>(y,x) == cv::Vec3b(255,255,255) ) {
count_white++;
}
else if ( imgROI.at<cv::Vec3b>(y,x) == cv::Vec3b(0,0,0) ) {
count_black++;
}
}
}
wont work, since there is no complete white or black one's. Only various shades of gray. Is there a way to use some threshold to sort them in black or white counters? Or maybe function to increase contrast and convert them into absolute white or black colors?
I do not know enough about your approach, but you can use threshold two times: one for almost white, and one for almost black, then use countNonZero to get the number of white/black pixels. Be careful to put on white all the pixels that you want (make white the almost black pixels, so you can count non zeros). Sorry, but I do not have enough time to create a nice answer
Any advice is helpful for me. Thanks for the links, i will keep an eye them right now.
For now did it with
and then just counted black & white's with previous func
If you have just 2 types of pixels, then you can do
numOfWhitePixels = contNonZero
and thennumOfBlackPixels = imgROI.cols * imgROI.rows - numOfWhitePixels
I try'ed to use your way as
but i got terminal crash with this error:
Your image
partROI1
is not binary (0 and 1). Have you threshold it? How? You should usecv::THRESH_BINARY
orcv::THRESH_BINARY_INV
. That is why I have said you shall threshold it 2 times: one for almost white pixels (with a threshold of 240 andcv::THRESH_BINARY
) and one for almost black pixels (with a threshold of 20 andcv::THRESH_BINARY_INV
) and then countNonZero for each case. You can adapt your thresholds to your approachdid it for now with this code.
since i were using a ROI of an image
helped
The error happens in the first or the second call of the countNonZero? You have some problems there:
threshold( partROI1, partROI1, 20, 255, THRESH_BINARY );
is changing the initial image if you have done something likecv::Mat partROI1 = initImage(roiRect);
(useinitImage(roiRect).clone
if that is the case)threshold( partROI1, partROI1, 240, 255, THRESH_BINARY_INV );
and inverse it.So, as I have said, do an imshow after each step to see exactly what are you doing
no, error doesn't show up anymore
cvtColor(partROI, partROI, CV_BGR2GRAY);
helped me to fix that. And yes, i were first counting the white pixels withTHRESH_BINARY
and then inverting them withTHRESH_BINARY_INV
and counting again the black ones. But you are right and this way will be more efficientThat approach is ok, if you have just white and black pixels in the image and no gray values (that means you so not want only the white and black pixels from an image that may contain gray values too). So the problem was that you were trying to apply threshold on a RGB image...