首页 > 其他 > 详细

How to remove the small blobs?

时间:2017-03-06 19:15:46      阅读:320      评论:0      收藏:0      [点我收藏+]

How to remove the small blobs?

I want to erase the small white spots areas to keep the largest area (white colour) in the picture:

【这个显然易见是一个形态学的问题】

Before

技术分享

I used findContours and found the largest area then used drawContours. I got the following result:

技术分享

My code【他的这种写法,显然不是使用轮廓的好方法。轮廓的处理应该是在形态学后面的,而且寻找联通区域也能够解决这个问题。】

 findContours(image, vtContours, vtHierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

for (int i = 0; i < vtContours.size(); i++)
{
    double area = contourArea(vtContours[i]);

    if (area <= 100) {
        continue;
    }

    // Get only one
    if (area > dMaxArea)
    {
        dMaxArea = area;
        nSavedContour = i;
    }

}

if (nSavedContour == -1)
{
    return false;
}

image = Scalar::all(0);
drawContours(image, vtContours, nSavedContour, Scalar(255), CV_FILLED, 8);

2 answers

You can use morphological operators like erode dilate or closing opening.

If you want to draw hole in your surface you have to use RETR_TREE instead of CV_RETR_EXTERNAL in findContours

About hierarchy :Original image is :

技术分享

Contours with hierarchy are

0 = [-1, -1, 1, -1] // contour 0 :-1 no next contour,-1  no previous contour, 1 contour #1 is a child, -1 no parent contour  
1 = [3, -1, 2, 0]  // contour 1 :-3 next contour,-1  no previous contour, 1 contour #2 is a child, 0 is parent contour  
2 = [-1, -1, -1, 1]
3 = [-1, 1, -1, 0]

技术分享

program is :

 Mat img = imread("C:/Users/Laurent.PC-LAURENT-VISI/Desktop/14887743804853655.jpg", CV_LOAD_IMAGE_GRAYSCALE);
imshow("original", img);
Mat y;
threshold(img, y, 50, 255, THRESH_BINARY);
imshow("threshold", y);
double ccMin, ccMax;
findContours(y, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
Mat c = Mat::zeros(img.size(), CV_8U);
for (int i = 0; i <contours.size(); i++)
{
    cout<<i<<" = "<<hierarchy[i]<<"\n";
}
for (int i = 0; i <contours.size(); i++)
{
    drawContours(c, contours, i, Scalar(255), 1, LINE_8, hierarchy, 0);
    putText(c,format("%d",i),contours[i][0], FONT_HERSHEY_SIMPLEX,0.5,Scalar(255));
}
imshow("ctr",c);
imwrite("c.png",c);
waitKey(0);
edit flag offensive link

Comments

Thank for supporting. I used morphological operators. But I want to use based on findContours. After change RETR_TREE instead of CV_RETR_EXTERNAL, what do I need to do? Tks!

 

updated 3 hours ago

If the problem you‘re asking for help with is the contour being filled in, probably the easiest way to make it how you want is to use that filled in contour as a mask on your image:

Mat mask = Mat::zeros(image.size(), CV_8U);
Mat newImage;
drawContours(mask, vtContours, nSavedContour, Scalar(255), CV_FILLED, 8);
image.copyTo(newImage, mask);

Then you‘ll have the contour you want in newImage.

Also if you want the largest contour, it‘s probably easiest to just sort the vector of contours. This is the function I always use for that:

void sortContours(vector<vector<Point>>& contours)
{
    auto contourComparator = [](vector<Point> a, vector<Point> b) { return contourArea(a) > contourArea(b); };
    sort(contours.begin(), contours.end(), contourComparator);
}
 

Then the largest one will just be the first one in the vector, so it would just be this to make the mask:

sortContours(vtContours);
drawContours(mask, vtContours, 0, Scalar(255), CV_FILLED, 8);

Comments





How to remove the small blobs?

原文:http://www.cnblogs.com/jsxyhelu/p/6511409.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!