clarkk
clarkk

Reputation: 27679

How to calculate the black / white ratio of pixels inside a contour

How is it possible to calculate the black / white ratio of the pixels inside the outline of a contour (not the bounding box)?

The image is pre-processed with cv::threshold(src, img, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU); and then inverted img = 255 - img;

I look for the retangular outline of the table (contour) via cv::RETR_EXTERNAL.. I want to calculate the black pixels inside the contour

There can be other components in the image so I can't just count all non-zero pixels

This is the original image before binarized and inverted

enter image description here

Upvotes: 1

Views: 1133

Answers (2)

Bahramdun Adil
Bahramdun Adil

Reputation: 6079

You cannot calculate the white and black ratio of a contour, because what is a contour? A group of white pixels which are connected which each other calls contour, so a contour does not contain any black pixel if it does, it calls hole inside the contour.

And also a contour does not have a specific shape.

So you can do it by Bounding Rectangle the rectangle around the contour then you will be to calculate the black and white ratio inside the rectangle.

enter image description here

Upvotes: 1

Miki
Miki

Reputation: 41765

I think there's some confusion about terminology. A contour is simply a sequence of points. If you draw them as a closed polygon (e.g. with cv::drawContours), all the points inside the polygon will be white.

You can however use this mask to count the white or black pixels on your thresholded image:

cv::Mat1b bw_image = ...

std::vector<std::vector<cv::Point>> contours;
cv::findContours(bw_image, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);

for(size_t i=0; i<contours.size(); ++i)
{
    cv::Mat1b contour_mask(bw_image.rows, bw_image.cols, uchar(0));
    cv::drawContours(contour_mask, contours, i, Scalar(255), cv::FILLED);

    int total_white_inside_contour = cv::countNonZero(mask);
    int white_on_image_inside_contour = cv::countNonZero(bw_image & mask);
    int black_on_image_inside_contour = total_white_inside_contour - white_on_image_inside_contour;
}

Upvotes: 1

Related Questions