# How to eliminate small contours in a binary image?

I am currently working on image processing project. I am using Opencv 3.x.x with VC++.

My code:

Mat result;
vector<vector<Point> >contours;
vector<Vec4i>hierarchy;
int savedContour = -1;
double maxArea = 0.0;
// Find the largest contour
findContours(binarayImage, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point());
for (int i = 0; i< contours.size(); i++)
{
double area = contourArea(contours[i]);
if (area > maxArea)
{
maxArea = area;
savedContour = i;
}
}
drawContours(result, contours, savedContour, Scalar(255), CV_FILLED, 8);


The binary image which I obtained :

The result/output image which I want to obtain :

but when I applied the above code, the result was

did not look like I expected.

Help me! Thank you!

P/s: I know this problem is caused by drawContours. But I have no way to fix it.

edit retag close merge delete

Hi, take the biggest contour instead.

( 2016-12-28 23:27:37 -0500 )edit

Yeah. I took the biggest contour. But when I used drawContours, it looked like the last picture

( 2016-12-29 00:46:14 -0500 )edit

Sort by » oldest newest most voted

you're almost there ! all it needs is to actually apply the mask from drawContours !

(bitwise_and it with your binary image)

Mat result;
vector<vector<Point> >contours;
vector<Vec4i>hierarchy;
int savedContour = -1;
double maxArea = 0.0;
// Find the largest contour
//
//// findContours will "eat" the input image, so clone the binary Mat, we need it later:
//
findContours(binarayImage.clone(), contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point());
for (int i = 0; i< contours.size(); i++)
{
double area = contourArea(contours[i]);
if (area > maxArea)
{
maxArea = area;
savedContour = i;
}
}
drawContours(result, contours, savedContour, Scalar(255), CV_FILLED, 8);

// apply the mask:
binarayImage &= result;

more

When you find contours, you only find the boundaries, and each boundary is a separate contour. So when you eliminate the small ones, you eliminate the small contours inside the large one. You either need to explicitly keep all contours that are inside the large one (use the hierarchy output variable), or use connected components instead.

Connected Components might be closer to what you want. It finds all the blobs of white pixels. You simply filter the ones that have too small an area, and it keeps both the inner and outer boundaries.

Which one is best depends on what exactly you're doing with them, but both should work.

more