1

我正在使用 opencv 2.4.13

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

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

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

谢谢

4

2 回答 2

3

添加到@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);

}
于 2018-02-05T08:33:08.130 回答
2

最简单的可能是使用findContours.

您可以计算由 计算的第 i 个组件的轮廓connectedComponents(WithStats),因此它们与您的标签对齐。使用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();
    }
}
于 2016-06-10T10:49:34.723 回答