opencv查找连接组件的周长

时间:2016-06-10 09:56:05

标签: c++ opencv connected-components

我正在使用opencv 2.4.13

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

方法arcLength不能正常工作,因为我拥有组件的所有点,而不仅仅是轮廓。

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

由于

2 个答案:

答案 0 :(得分:1)

最简单的事情可能就是使用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();
    }
}

答案 1 :(得分:1)

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

}