opencv查找连通分量的周长

opencv find perimeter of a connected component

我正在使用 opencv 2.4.13

我试图找到连通分量的周长,我正在考虑使用 ConnectedComponentWithStats 但它没有 return 周长,只有面积、宽度等。 . 有一种方法可以找到具有轮廓但不是相反的区域(我的意思是一个组件,而不是整个图像)。

方法 arcLength 效果不佳,因为我拥有组件的所有点,而不仅仅是轮廓。

我知道有一种 BF 方法可以通过遍历组件的每个像素并查看他是否有不在同一组件中的邻居来找到它。但我想要一个成本更低的功能。 否则,如果您知道 link 具有通过方法 findContours 找到的轮廓的组件,它也适合我。

谢谢

最简单的可能就是使用findContours

您可以计算由 connectedComponents(WithStats) 计算的第 i 个分量的轮廓,因此它们与您的标签对齐。使用 CHAIN_APPROX_NONE 您将获得轮廓中的所有点,因此矢量的 size() 已经是周长的度量。您最终可以使用 arcLength(...) 来获得更准确的结果:

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();
    }
}

添加到@Miki 的回答中,这是找到连通分量周长的更快方法

//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);

}