opencv find perimeter of a connected component

我只是一个虾纸丫 提交于 2019-12-04 05:52:02

问题


I'm using opencv 2.4.13

I'm trying to find the perimeter of a connected component, I was thinking of using ConnectedComponentWithStats but it doesn't return the perimeter, only the area, width, etc... There is a method to find the area with the contour but not the opposite (with one component i mean, not the entire image).

The method arcLength doesn't work as well beause i have all the points of the component, not only the contour.

I know there is a BF way to find it by iterating through each pixel of the component and see if he has neighbors which aren't in the same component. But I'd like a function which costs less. Otherwise, if you know a way to link a component with the contours found by the method findContours, it suits me as well.

Thanks


回答1:


The easiest thing is probably to use findContours.

You can compute the contour on the i-th component computed by connectedComponents(WithStats) , so they are aligned with your labels. Using CHAIN_APPROX_NONE you'll get all the points in the contour, so the size() of the vector is already a measure of the perimeter. You can eventually use arcLength(...) to get a more accurate result:

Mat1i labels;
int n_labels = connectedComponents(img, labels);

for (int i = 1; i < n_labels; ++i)
{
    // Get the mask for the i-th contour
    Mat1b mask_i = labels == i;

    // Compute the contour
    vector<vector<Point>> contours;     
    findContours(mask_i.clone(), contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);

    if (!contours.empty())
    {
        // The first contour (and probably the only one)
        // is the one you're looking for

        // Compute the perimeter
        double perimeter_i = contours[0].size();
    }
}



回答2:


Adding to @Miki's answer, This is a faster way to find the perimeter of the connected component

//getting the connected components with statistics
cv::Mat1i labels, stats;
cv::Mat centroids;

int lab = connectedComponentsWithStats(img, labels, stats, centroids);

for (int i = 1; i < lab; ++i)
{
    //Rectangle around the connected component
    cv::Rect rect(stats(i, 0), stats(i, 1), stats(i, 2), stats(i, 3));

    // Get the mask for the i-th contour
    Mat1b mask_i = labels(rect) == i;

    // Compute the contour
    vector<vector<Point>> contours;     
    findContours(mask_i, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);

    if(contours.size() <= 0)
         continue;        

    //Finding the perimeter
    double perimeter = contours[0].size();
    //you can use this as well for measuring perimeter
    //double perimeter = arcLength(contours[0], true);

}


来源:https://stackoverflow.com/questions/37745274/opencv-find-perimeter-of-a-connected-component

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