Как обнаружить простые геометрические фигуры с помощью OpenCV
У меня есть этот проект, где мне нужно (на iOS), чтобы обнаружить простые геометрические фигуры внутри изображения.
После поиска в интернете я пришел к выводу, что лучший инструмент для этого - OpenCV. Дело в том, что еще два часа назад я понятия не имел, что такое OpenCV, и я никогда даже ничего удаленно не делал, включая обработку изображений. Мой основной опыт это JS/HTML,C#,SQL,Objective-C...
С чего мне начать?
Я нашел этот ответ, который мне удалось переварить, и, читая уже другие материалы, я понимаю, что OpenCV должен возвращать массив фигур с точками / углами, это правда? Также, как это будет представлять круг или полукруг? А как насчет ориентации формы?
Знаете ли вы какой-нибудь демонстрационный проект iOS, который может продемонстрировать аналогичную функциональность?
3 ответа
Если у вас есть только эти правильные фигуры, существует простая процедура:
- Найти контуры на изображении (изображение должно быть двоичным, как указано в вашем вопросе)
- Приблизьте каждый контур, используя
approxPolyDP
функция. - Сначала проверьте количество элементов в приближенных контурах всех фигур. Это признать форму. Например, у квадрата будет 4, у пятиугольника - 5. У кругов будет больше, я не знаю, поэтому мы его находим. (Я получил 16 за круг и 9 за полукруг.)
- Теперь назначьте цвет, запустите код для вашего тестового изображения, проверьте его номер, залейте его соответствующими цветами.
Ниже приведен мой пример на Python:
import numpy as np
import cv2
img = cv2.imread('shapes.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,1)
contours,h = cv2.findContours(thresh,1,2)
for cnt in contours:
approx = cv2.approxPolyDP(cnt,0.01*cv2.arcLength(cnt,True),True)
print len(approx)
if len(approx)==5:
print "pentagon"
cv2.drawContours(img,[cnt],0,255,-1)
elif len(approx)==3:
print "triangle"
cv2.drawContours(img,[cnt],0,(0,255,0),-1)
elif len(approx)==4:
print "square"
cv2.drawContours(img,[cnt],0,(0,0,255),-1)
elif len(approx) == 9:
print "half-circle"
cv2.drawContours(img,[cnt],0,(255,255,0),-1)
elif len(approx) > 15:
print "circle"
cv2.drawContours(img,[cnt],0,(0,255,255),-1)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Ниже вывод:
Помните, это работает только для правильных форм.
В качестве альтернативы, чтобы найти круги, вы можете использовать houghcircles
, Вы можете найти учебник здесь.
Что касается iOS, разработчики OpenCV разрабатывают некоторые образцы iOS этим летом, поэтому посетите их сайт: www.code.opencv.org и свяжитесь с ними.
Вы можете найти слайды их учебника здесь: http://code.opencv.org/svn/gsoc2012/ios/trunk/doc/CVPR2012_OpenCV4IOS_Tutorial.pdf
Ответ зависит от наличия других форм, уровня шума, если таковой имеется, и от инвариантности, которую вы хотите обеспечить (например, вращение, масштабирование и т. Д.). Эти требования будут определять не только алгоритм, но и необходимые этапы предварительной обработки для извлечения характеристик.
Сопоставление шаблонов, которое было предложено выше, хорошо работает, когда фигуры не повернуты и не масштабированы, и когда вокруг нет похожих фигур; другими словами, он находит лучший перевод в изображении, где расположен шаблон:
double minVal, maxVal;
Point minLoc, maxLoc;
Mat image, template, result; // template is your shape
matchTemplate(image, template, result, CV_TM_CCOEFF_NORMED);
minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc); // maxLoc is answer
Геометрическое хеширование - хороший метод для получения инвариантности с точки зрения вращения и масштабирования; этот метод потребует выделения некоторых точек контура.
Обобщенное преобразование Хафа может позаботиться об инвариантности, шумах и будет иметь минимальную предварительную обработку, но его немного сложнее реализовать, чем другими методами. OpenCV имеет такие преобразования для линий и окружностей.
В случае, когда количество фигур ограничено, вычисление моментов или подсчет вершин выпуклой оболочки может быть самым простым решением: структурный анализ openCV
Вы также можете использовать сопоставление с шаблоном для обнаружения фигур внутри изображения.