2016-03-14 2 views
2

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

enter image description here

Я применен подходящий порог и получил этот

enter image description here

Теперь я использовал контур, чтобы найти внутренние черные пятна. Я использовал зеленый цвет, чтобы обозначить внешнюю границу и красный для внутренних. Это то, что я получил: - enter image description here

Я извлек капли, используя красный цвет. Но я хотел бы извлечь только те, которые не имеют зеленого внутри них или, по крайней мере, дают внутреннюю границу только тем, у которых нет другого контура внутри них. так или иначе?

EDIT-1: - Я думал о поиске координат зеленых и красных пикселей и преобразовании всех прочитанных пикселей в зеленый, если они очень близки друг к другу. но кто-нибудь знает, как получить координаты?

EDIT-2 Я следовал методу Дермана и получил 80% результата. проверить другой источник ПОС и маску enter image description here enter image description here

теперь следует входы по Derman, я получил это enter image description here

код четко определяет контуры обозначены цифры 1 и 3 (в виде зеленого и красного цвета) на основе факт, что они либо имеют, либо dsnt имеют дочерние контуры. Но контур 2 явно такой же, как контур 1, и имеет контуры ребенка, но все же он воспринимается как красный. Я поделюсь вам, ребята, код, я знаю, что все это может занять небольшое изменение, но это, кажется, ускользает от механиче-

Mat binMask;  
Mat lung_src; 
vector<std::vector<cv::Point>> contours; 
vector<cv::Vec4i> hierarchy; 
int count = 0; 

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

for (int i = 0; i < contours.size(); i++) 
{ 
    if (hierarchy[i][2] != -1) // means it has child contour 
    {   
     if (count>1)// number of child countors,if its greater than 1 then green else red 
     { 
      drawContours(lung_src, contours, i, Scalar(0, 255, 0), 1, 8, hierarchy, 0, Point());     
     } 
     else // means it's count is 1 or less 
     { 
      drawContours(lung_src, contours, i, Scalar(0, 0, 255), 1, 8, hierarchy, 0, Point()); 
     } 
     count++; 
    }   
    else // means it doesn't have any child contour 
    { 
     drawContours(lung_src, contours, i, Scalar(0, 0, 255), 1, 8, hierarchy, 0, Point()); 
    } 
} 
imshow("lung", lung_src); 
imwrite("lung.tiff", lung_src); 

lung_src это показано выше красный/зеленый контур изображения.

ответ

3

Для определения того, является ли один контур внутри другого, вы можете использовать структурные характеристики иерархии контуров. Например, в вашем случае, вы можете обнаружить первые контуры, используя что-то вроде этого:

cv::Mat inputImg = cv::imread("keVZc.png", CV_LOAD_IMAGE_GRAYSCALE);  
cv::Mat binMask = cv::Mat::zeros(inputImg.size(), inputImg.type()); 
cv::threshold(inputImg, binMask, 28, 255, CV_THRESH_BINARY); 

cv::Mat cannyOutput = cv::Mat::zeros(binMask.size(), binMask.type()); 
cv::Canny(binMask, cannyOutput, 28, 28 * 2, 3); 

std::vector<std::vector<cv::Point>> contours; 
std::vector<cv::Vec4i> hierarchy; 
cv::findContours(cannyOutput, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0)); 

Затем, используя иерархию, вы можете решить, имеет ли этот контур родитель, ребенок и т.д. Общая структура иерархии, как это:

[next contour, previous contour, child contour, parent contour] 

в previous и next контуры являются те, принадлежащие одному и тому же уровню, что и входной контур. Если входной контур имеет дочерний элемент, то он даст вам дочернюю метку, иначе его значение будет -1, что аналогично случаю для родителей.

Таким образом, вы можете проверить, является ли контур внутри другой, как это:

for(int i = 0; i < contours.size(); i++) 
{ 
    if(hierarchy[i][2] != -1) // means it has child contour 
    { 
     // do something with it 
    } 
    else // means it doesn't have any child contour 
    { 
     // do something with it 
    } 
} 

Для сравнения ли два контура расположен слишком близко друг к другу для того, чтобы фильтровать их, вы можете использовать измерение расстояния (норма) между ними.Нечто подобное помогло бы:

for(int i = 0; i < contours.size(); i++) 
{ 
    int prvIndx = hierarchy[i][0]; // coordinates of previous contour 
    int nxtIndx = hierarchy[i][1]; // coordinates of next contour 

    std::vector<cv::Point> prvPoint = contours[prvIndx]; 
    std::vector<cv::Point> nxtPoint = contours[nxtIndx]; 

    // calculate norm of these two points 
    double distance = cv::norm(point1, point2); 

    // use a threshold value to decide what to do 
    if(double <= 40.0) // change the value according to your situation 
    { 
     // you decide what to do here 
    } 

} 

Более подробно об иерархии контура, посмотри на следующие ссылках:

ref1: Finding contours in your image

ref2: Contours hierarchy

Надеется, что это помогает!

+0

В родительском разделе значение указывает, какой контур является родительским. Например, '[-1, 2, -1, 7]' означает, что его родительский 7-й контур. Таким образом, вы можете получить родителя с чем-то вроде «контуров [7]». – Derman

+0

Спасибо за помощь: D –

+0

Если вы считаете, что мой ответ помог, пожалуйста, не забудьте принять его. – Derman

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