Ответ 1
Вам не нужно делать обнаружение кромок здесь. Просто порог для двоичного изображения, а затем найдите blobs (cvFindContours). Вы можете использовать cvContourArea для каждого возвращаемого CvSeq, чтобы найти его область.
Я пишу небольшое приложение для обнаружения фигуры. Что мне нужно сделать в первую очередь, так это найти наиболее значимую фигуру на изображении. Я начал с некоторой предварительной обработки, включая преобразование изображения в оттенки серого, пороговое значение и обнаружение краев. Изображение до и после этих операций представлено ниже
Перед
После
Итак, вы видите, что основная фигура видна (однако она немного разбросана), а также есть некоторые шумы (маленькие деревья и т.д.). Мне нужно сделать так, чтобы как-то извлечь только самую значимую форму (самую большую) - в этом случае это башня. То, что я хотел сделать, это использовать функцию поиска контура в opencv, а затем как-то aproximate найти conturs с полигоном. Тогда я (каким-то образом) вычислил бы площадь гравюр и выберет только самую большую. До сих пор я управлял (только), чтобы найти контуры, используя
cvFindContours(crated,g_storage,&contours);
Я знаю, что есть
cvApproxPoly
однако я не могу получить полезную информацию для результата этой функции. Может ли кто-нибудь сказать мне, можно ли вычислить область контура или приблизить контур с полигоном. Может быть, вам лучше понять, как извлечь только самую значимую фигуру?
Вам не нужно делать обнаружение кромок здесь. Просто порог для двоичного изображения, а затем найдите blobs (cvFindContours). Вы можете использовать cvContourArea для каждого возвращаемого CvSeq, чтобы найти его область.
Если у вас всегда есть контролируемый фон, я бы пошел на эти шаги (как это предложил также @damian):
Ваша основная проблема заключается в том, что контур башни рассеивается. Трудно воссоздать весь контур из этих маленьких кусочков. Оптимизируйте фазу обнаружения края (попробуйте 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 ));
Вам нужно будет настроить параметры. Он использовался для обнаружения прямоугольников.
Вы можете использовать морфологические операции для подавления "контурного шума" (расширение в вашем случае). Но вы должны помнить, что удобство использования морфологических операций зависит от текущей задачи. Например, если у вас есть два объекта, которые расположены близко друг к другу, расширение может сделать из них один объект.