1

У меня есть этот исходный файлподсчета количества дочерних контуров внутри контура в OpenCV

enter image description here

и я применил бинарную пороговую, чтобы получить этот

enter image description here

Я использовал контуры различают те, которые имеют дочерние контуры и те, которые не соответствуют. Итоговый результат:

enter image description here

Но как я могу подсчитать количество контуров детей, которые содержат каждый зеленый контур ?. Это код, который я использовал: -

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- я добавил код из Хумама в конце, чтобы проверить это:

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 

ответ

0

От OpenCV documentation:

Иерархия - Дополнительный выходной вектор, содержащий информацию о топологии изображения . Он имеет столько же элементов, сколько количество контуров. Для каждого i-го контура контура [i] иерархия элементов [i] [0], hiearchy i, hiearchy [i] [2] и hiearchy [i] [3] установлены на 0-основанные индексы в контурах следующего и предыдущего контуров на уровне одинакового иерархического уровня, первого дочернего контура и родительского контура , соответственно. Если для контура i нет следующих, предыдущих, родительских или вложенных контуров, то соответствующие элементы иерархии будут [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; 
    } 
} 
+0

Извините, но ваш код не дает желаемого результата. –

+0

Не могли бы вы дать пояснения, что «не дает желаемого результата». Я отредактировал ошибку, которая была в коде. Вы можете попробовать еще раз –

+0

@ Humam-можете проверить это? –

Смежные вопросы