How to filter small segments from image in OpenCV?

怎甘沉沦 提交于 2019-12-22 10:55:17

问题


I am printing the Contours in the following way:

std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours( mask, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_TC89_KCOS);
for ( size_t i=0; i<contours.size(); ++i )
{
    cv::drawContours( img, contours, i, Scalar(200,0,0), 1, 8, hierarchy, 0, Point() ); 
    cv::Rect brect = cv::boundingRect(contours[i]);
    cv::rectangle(img, brect, Scalar(255,0,0));
}

Once I have a binnary image, I want to eliminate the smaller contours. Any suggestions on how to do so?

MY INPUT PICTURE:

WHAT I WANT TO ACHIEVE:

EDIT:

I am trying to get rid of the smaller segments. Any hints?


回答1:


I've built a function that only prints points that belong to the bigger segments. It uses the pointPolygonTest, an awesome OpenCV function that can say if a point is inside, outside or at the bounds of a given contour. Check it out:

// Gets only the biggest segments
Mat Morphology::threshSegments(Mat &src, double threshSize) {
    // FindContours:
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    Mat srcBuffer, output;
    src.copyTo(srcBuffer);
    findContours(srcBuffer, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_TC89_KCOS);

    vector<vector<Point> > allSegments;

    // For each segment:
    for (size_t i = 0; i < contours.size(); ++i) {
        cv::drawContours(srcBuffer, contours, i, Scalar(200, 0, 0), 1, 8, hierarchy, 0, Point());
        cv::Rect brect = cv::boundingRect(contours[i]);
        cv::rectangle(srcBuffer, brect, Scalar(255, 0, 0));

        int result;
        vector<Point> segment;
        for (unsigned int row = brect.y; row < brect.y + brect.height; ++row) {
            for (unsigned int col = brect.x; col < brect.x + brect.width; ++col) {
                result = pointPolygonTest(contours[i], Point(col, row), false);
                if (result == 1 || result == 0) {
                    segment.push_back(Point(col, row));
                }
            }
        }
        allSegments.push_back(segment);
    }

    output = Mat::zeros(src.size(), CV_8U);
    int totalSize = output.rows*output.cols;
    for (int segmentCount = 0; segmentCount < allSegments.size(); ++segmentCount) {
        vector<Point> segment = allSegments[segmentCount];
        if(segment.size() > totalSize*threshSize){
            for (int idx = 0; idx < segment.size(); ++idx) {
                output.at<uchar>(segment[idx].y, segment[idx].x) = 255;
            }
        }
    }

    return output;
}



回答2:


I would suggest using morphological opening to get rid of the smaller blobs, followed by a morphological hole filling.



来源:https://stackoverflow.com/questions/19732431/how-to-filter-small-segments-from-image-in-opencv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!