обнаружение фигур - аппроксимация контуров с помощью OpenCV - PullRequest
15 голосов
/ 12 июня 2011

Я пишу небольшое приложение для определения формы. В первую очередь мне нужно найти наиболее значимую форму на изображении. Я начал с некоторой предварительной обработки, включая преобразование изображения в градации серого, определение порога и определение границ. Изображение до и после этих операций представлено ниже

До

enter image description here

* После 1008 *

enter image description here

Итак, как вы можете видеть, основная фигура видна (однако она немного разбросана), а также есть некоторые шумы (маленькие деревья и т. Д.). Мне нужно как-то извлечь только наиболее значимую фигуру (самую большую) - в данном случае это башня. То, что я хотел сделать, это использовать функцию поиска контуров в opencv, а затем каким-то образом приблизить найденные контуры с полигоном. Затем я бы (как-то) вычислил площадь счетчиков и выбрал только самый большой. Пока мне удалось (только) найти контуры, используя

cvFindContours(crated,g_storage,&contours);

Я знаю, что есть

cvApproxPoly

, однако я не могу получить какую-либо полезную информацию для результата этой функции. Может кто-нибудь сказать мне, если это возможно, чтобы рассчитать площадь контура или приблизить контур с полигоном. Может быть, у вас есть идея, как извлечь только наиболее значимые фигуры?

Ответы [ 4 ]

8 голосов
/ 13 июня 2011

Здесь вам не нужно определять края. Просто порог к бинарному изображению, а затем найдите капли (cvFindContours) на этом. Вы можете использовать cvContourArea для каждого возвращенного CvSeq, чтобы найти его область.

6 голосов
/ 27 июня 2011

Если у вас всегда есть контролируемый фон, я бы пошел на следующие шаги (как предложено также @damian):

  1. Бинаризация , т.е. создание изображения, такого какфон = 0 и области объекта = 1 (или 255).После этого у вас будет несколько белых областей на вашем изображении.Есть несколько способов сделать это, но если ваш фон контролируется, вы можете использовать фиксированный порог.Обратите внимание, что здесь вы удалили шум внутри объектов.В двоичном изображении вы всегда можете использовать морфологическое открытие / закрытие, чтобы сгладить объекты
  2. Используйте cvFindContours , чтобы найти все объекты: теперь должно быть проще.Заполните меньшие контуры цветом фона, используя cvFloodFill .
5 голосов
/ 13 июня 2011

Ваша главная проблема в том, что контур башни разбросан. Из этих маленьких кусочков будет сложно воссоздать весь контур. Оптимизируйте фазу обнаружения краев (попробуйте cvAdaptiveThreshold) или используйте другой подход (возможно, что-то вроде сегментация объекта )

После того, как у вас есть контур в одной части, вы можете проверить его область следующим образом:

CvSeq* convex_hull=cvConvexHull2( contour, storage, CV_CLOCKWISE, 2 );
CvSeq* quad=cvApproxPoly(convex_hull, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contour)*0.02, 0);
float size=fabs(cvContourArea( quad,CV_WHOLE_SEQ,0 ));

Вам нужно будет настроить параметры. Он был использован для обнаружения прямоугольников.

2 голосов
/ 13 июня 2011

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

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