【问题标题】:counting the number of child contours inside a contour in opencv计算opencv中轮廓内的子轮廓数
【发布时间】:2023-03-21 15:21:01
【问题描述】:

我有这个源图片

我已经应用了二进制阈值来得到这个

我使用轮廓来区分具有子轮廓的轮廓和没有子轮廓的轮廓。结果图片是

但是如何计算每个绿色轮廓包含的子轮廓的数量?这是我用过的代码:-

Mat binMask = lung;// the thresholded image
Mat lung_src = imread("source.tiff");// the source image
//imshow("bin mask", binMask);
vector<std::vector<cv::Point>> contours;
vector<cv::Vec4i> hierarchy;
int count = 0, j;

double largest_area = 0;
int largest_contour_index = 0;

findContours(binMask, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0));

for (int i = 0; i < contours.size(); i++)
{
    double a = contourArea(contours[i], false);  //  Find the area of contour
    if (a>largest_area)
    {
        largest_area = a;
        largest_contour_index = i;
    }
    for (j = 0; j <= i; j++)
    {
        if (hierarchy[j][2] != -1) // means it has child contour
        {

                drawContours(lung_src, contours, j, Scalar(0, 255, 0), 1, 8, hierarchy, 0, Point());

        }           
        else  // means it doesn't have any child contour
        {
            drawContours(lung_src, contours, j, Scalar(0, 0, 255), 1, 8, hierarchy, 0, Point());
        }
    }
}
drawContours(lung_src, contours, largest_contour_index, Scalar(255, 0, 0), 1, 8, hierarchy, 0, Point());
imshow("lung-mapped", lung_src);

EDIT-1- 我在最后添加了来自 Humam 的代码以进行检查:

std::vector<int> number_of_inner_contours(contours.size(), -1);
int number_of_childs = 0;
for (size_t i = 0; i < contours.size(); i++)
{

    int first_child_index = hierarchy[i][2];
    if (first_child_index >= 0)
    {
        int next_child_index = hierarchy[first_child_index][0];
        if (number_of_inner_contours[next_child_index]<0)
        {
            number_of_childs = number_of_inner_contours[next_child_index];
        }
        else
        {
            while (next_child_index >= 0)
            {
                next_child_index = hierarchy[next_child_index][0];
                ++number_of_childs;
            }
            number_of_inner_contours[i] = number_of_childs;
        }
    }
    else
    {
        number_of_inner_contours[i] = 0;
    }
    cout << "\nThe contour[" << i << "] has " << number_of_inner_contours[i] << "child contours";
}

但我得到的输出是这样的:

      The contour[456 ] has 0 child contours
      The contour[457 ] has 0 child contours
      The contour[458 ] has 0 child contours
      The contour[459 ] has -1 child contours

【问题讨论】:

    标签: c++ opencv image-processing image-segmentation opencv-contour


    【解决方案1】:

    来自OpenCV documentation

    hierarchy – 可选输出向量,包含有关 图像拓扑。它具有与轮廓数一样多的元素。为了 每个第 i 个轮廓 contours[i] ,元素hierarchy[i][0] , hiearchyi 、 hiearchy[i][2] 和 hiearchy[i][3] 设置为 下一个和前一个轮廓的轮廓中基于 0 的索引 同一层级,第一个子轮廓和父轮廓 轮廓,分别。如果轮廓 i 没有下一个, 上一个、父级或嵌套的轮廓,对应的元素 hierarchy[i] 将是负数。

    这是完成这项工作的未经测试的代码:

    std::vector<size_t> number_of_inner_contours;
    number_of_inner_contours.reserve(contours.size());
    for (size_t i = 0; i < contours.size(); i++){
        size_t number_of_childs = 0;   
        auto first_child_index=hierarchy[i][2];
        if(first_child_index>=0){
            auto next_child_index=hierarchy[first_child_index][0];
            while (next_child_index>=0){
                next_child_index=hierarchy[next_child_index][0];
                ++number_of_childs;
            }
            number_of_inner_contours.emplace_back(number_of_childs);
        }
        else{
             number_of_inner_contours.emplace_back(0);
        }
    }
    

    使用动态编程的概念可以更好地完成这段代码。这也是第一次尝试:

    std::vector<int> number_of_inner_contours(contours.size(),-1);
    for (size_t i = 0; i < contours.size(); i++){
        auto number_of_childs = 0;   
        auto first_child_index=hierarchy[i][2];
        if(first_child_index>=0){
            auto next_child_index=hierarchy[first_child_index][0];
            if(number_of_inner_contours[next_child_index]<0){
                number_of_childs=number_of_inner_contours[next_child_index];
            }
            else{
                while (next_child_index>=0){
                    next_child_index=hierarchy[next_child_index][0];
                    ++number_of_childs;
                }
                number_of_inner_contours[i]=number_of_childs;
            }
        }
        else{
             number_of_inner_contours[i]=0;
        }
    }
    

    【讨论】:

    • 很抱歉,您的代码没有给出想要的结果。
    • 您能否澄清一下“没有给出预期的结果”。我编辑了代码中的错误。你可以再试一次
    • @Humam-你能看看这个吗?
    猜你喜欢
    • 2021-09-07
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    • 2016-09-25
    • 2022-01-23
    • 1970-01-01
    相关资源
    最近更新 更多