Распознавать открытые и закрытые формы opencv

Как обнаружить открытые и закрытые формы в OpenCV.

введите описание изображения здесь

Это простые образцы форм, которые я хочу обнаружить. Я обнаружил прямоугольник, используя findContours а также approxPolyDP и чем проверять угол между векторами.

Теперь я хочу обнаружить открытую форму, approxPolyDP функция имеет значение bool для закрытой формы, установленное в значение true, а также есть проверка для isCounterConvex по очкам вернулся, плюс contourArea ограничение.

Любые идеи, как я должен продолжать обнаруживать изображения такого рода.

14

Решение

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

Здесь мы будем использовать иерархию как

vector< Vec4i > hierarchy

где для i-го контура

hierarchy[i][0] = next contour at the same hierarchical level
hierarchy[i][1] = previous contour at the same hierarchical level
hierarchy[i][2] = denotes its first child contour
hierarchy[i][3] = denotes index of its parent contour

Если для контура i нет следующих, предыдущих, родительских или вложенных контуров, соответствующие элементы hierarchy[i] будет отрицательным. Увидеть findContours () функция для более подробной информации.

Таким образом, проверяя значение hierarchy[i][2] Вы можете решить, принадлежит ли контур замкнутому или нет, то есть для контура, если hierarchy[i][2] = -1 тогда нет ребенка и он принадлежит к открытому.

И еще одна вещь — в функции findContours () вы должны использовать CV_RETR_CCOMP, который извлекает все контуры и организует их в двухуровневую иерархию.

Вот код C ++, как это реализовать.

    Mat tmp,thr;
Mat src=imread("1.png",1);
cvtColor(src,tmp,CV_BGR2GRAY);
threshold(tmp,thr,200,255,THRESH_BINARY_INV);

vector< vector <Point> > contours; // Vector for storing contour
vector< Vec4i > hierarchy;
findContours( thr, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );

for( int i = 0; i< contours.size(); i=hierarchy[i][0] ) // iterate through each contour.
{
Rect r= boundingRect(contours[i]);
if(hierarchy[i][2]<0) //Check if there is a child contour
rectangle(src,Point(r.x-10,r.y-10), Point(r.x+r.width+10,r.y+r.height+10), Scalar(0,0,255),2,8,0); //Opened contour
else
rectangle(src,Point(r.x-10,r.y-10), Point(r.x+r.width+10,r.y+r.height+10), Scalar(0,255,0),2,8,0); //closed contour
}

Результат:

введите описание изображения здесь

24

Другие решения

Несмотря на правильность поставленной задачи, полезный ответ @Haris не следует воспринимать как общее решение для определения замкнутых контуров с использованием findContours ().

Одна из причин заключается в том, что заполненный объект не будет иметь внутреннего контура и поэтому будет возвращать hierarchy[i][2] = -1Значение этого теста само по себе ошибочно пометит такие контуры как «открытые».

Контур заполненного объекта не должен иметь дочерних или родительских элементов в иерархии контуров, т. Е. Находиться на верхнем уровне. Поэтому для обнаружения замкнутых контуров заполненных объектов потребуется как минимум дополнительная проверка: if(hierarchy[i][2] < 0 && hierarchy[i][3] < 0),

Я думаю, что ответ @Haris, возможно, сделал это косвенно, но я подумал, что стоит разъяснить это людям, таким как я, которые учатся использовать opencv.

4

Ответ зависит от вашего изображения, точнее, от того, сколько контуров задано, есть ли другие объекты, шум и т. Д. В простом случае заливки одного контура, начатого внутри замкнутого контура, не будет разливаться по всему изображению ; если начать снаружи, он не попадет в середину. Таким образом, вы бы сохранили некоторую белую область в обоих случаях.

0
По вопросам рекламы [email protected]