Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Contours opencv : How to eliminate small contours in a binary image

I am currently working on image processing project. I am using Opencv2.3.1 with VC++. I have written the code such that, the input image is filtered to only blue color and converted to a binary image. The binary image has some small objects which I don't want. I wanted to eliminate those small objects, so i used openCV's cvFindContours() method to detect contours in Binary image. but the problem is I cant eliminate the small objects in the image output. I used cvContourArea() function , but didn't work properly.. , erode function also didn't work properly.

So please someone help me with this problem..

The binary image which I obtained :

enter image description here

The result/output image which I want to obtain :

enter image description here

like image 611
Manoj M Avatar asked Apr 20 '12 00:04

Manoj M


People also ask

How do I remove vertical and horizontal lines from an image in Python?

One approach is to rotate the image 90 deg, then apply your same code, then rotate back 90 deg. Another approach is to change your horizontal kernel to a vertical kernel in your morphology.


2 Answers

Ok, I believe your problem could be solved with the bounding box demo recently introduced by OpenCV.

enter image description here

As you have probably noticed, the object you are interested at should be inside the largest rectangle draw in the picture. Luckily, this code is not very complex and I'm sure you can figure it all out by investigating and experimenting with it.

like image 193
karlphillip Avatar answered Sep 21 '22 17:09

karlphillip


Here is my solution to eliminate small contours. The basic idea is check the length/area for each contour, then delete the smaller one from vector container.

normally you will get contours like this

Mat canny_output; //example from OpenCV Tutorial
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
Canny(src_img, canny_output, thresh, thresh*2, 3);//with or without, explained later.
findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0,0));

With Canny() pre-processing, you will get contour segments, however each segment is stored with boundary pixels as a closed ring. In this case, you can check the length and delete the small one like

for (vector<vector<Point> >::iterator it = contours.begin(); it!=contours.end(); )
{
    if (it->size()<contour_length_threshold)
        it=contours.erase(it);
    else
        ++it;
}

Without Canny() preprocessing, you will get contours of objects. Similarity, you can also use area to define a threshold to eliminate small objects, as OpenCV tutorial shown

vector<Point> contour = contours[i];
double area0 = contourArea(contour);

this contourArea() is the number of non-zero pixels

like image 36
Mass Zhou Avatar answered Sep 21 '22 17:09

Mass Zhou