2016-08-01 2 views
2

Мне нужно извлечь самый внешний контур нескольких силуэтов, возможно, сохранить координаты контура по часовой стрелке или против часовой стрелки. Из того, что я прочитал, такой результат можно архивировать, используя OpenCV Canny + findContours. К сожалению, большинство силуэтов, которые я должен разработать, имеют зубчатые края или отверстия, поэтому «стандартная процедура» работает неправильно. Например, если мой образ достаточно просто и без отверстий, результат точно так, как я хочу это (только внешний контур и упорядоченных координаты): Cup exampleИзвлечение внешнего контура из силуэта

В случае снимков с дырками, я получаю сегментированный самый наружный контур (различные цвета, см. прикрепленные изображения), и он по-прежнему отображает внутренние отверстия в конечном изображении. Я получаю худшие результаты с зубчатыми краями. Отображаются отверстия, а контур сильно сегментирован (Cat). Holes and jagged edges

Код:

//add a small padding. Otherwise, in case of images where the border is partially cut out it won't be considered as a "closed" contour 
int topbottom = (int) (0.05*image.rows); 
int rightleft = (int) (0.05*image.cols); 
copyMakeBorder(image, image, topbottom, topbottom, rightleft, rightleft, BORDER_CONSTANT); 

//consider only alpha channel to create a silhouette 
Mat silhouette; 
vector<Mat> ch; 
split(image, ch); 

Canny(ch[3], silhouette, 100, 200); 

vector<vector<Point>> contours; 
vector<Vec4i> hierarchy; 

//find only the external contour 
findContours(silhouette, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); 

RNG rng(12345); 
Mat drawing = Mat::zeros(silhouette.size(), CV_8UC3); 
for(int i = 0; i < contours.size(); i++) 
{ 
    Scalar colour = Scalar(rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255)); 
    drawContours(drawing, contours, i, colour, 1, 8, hierarchy, 0, Point()); 
} 

Есть ли способ, чтобы избежать сегментации и удалить контуры отверстий?

+3

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

+0

Конечно! Вот некоторые из них: [Первый образец pic (Bed)] (http://labelmaterial.s3.amazonaws.com/shapes/2KGnQ5RjIoXZXmoXr723dXz.png) [Второй образец pic (Cat)] (http: //labelmaterial.s3 .amazonaws.com/shapes/2NXvn0zPaDGXLIoQJ9LuyVT.png) – Izzy88

+0

У вас есть хорошее изображение порога (2-е изображение в отверстиях и зубчатых краях). Теперь просто найдите самый большой контур из всех контуров и нарисуйте его. Вы получите только один внешний боковой контур, который вы хотеть. –

ответ

0

OpenCV имеет функцию под названием cv2.contourArea(), которая позволяет вам подсчитать площадь входного контура. Если у вас несколько контуров, используйте эту функцию, чтобы найти области всех ваших контуров и удалить все, кроме самого большого контура (один с наибольшей площадью, потому что контуры внутри этого большого контура не будут иметь большую площадь). После этого у вас останется только самый большой внешний контур.

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