Как обнаружить простые геометрические фигуры с помощью OpenCV

У меня есть этот проект, где мне нужно (на iOS) обнаруживать простые геометрические фигуры внутри изображения.

enter image description here

После поиска в Интернете я пришел к выводу, что лучшим инструментом для этого является OpenCV. Дело в том, что до двух часов назад я понятия не имел, что такое OpenCV, и я даже не отдал ничего, что связано с обработкой изображений. Мой главный опыт: JS/HTML, С#, SQL, Objective-C...

С чего начать?

Я нашел этот ответ, который мне удалось переварить, и, читая уже другие вещи, я понимаю, что OpenCV должен возвращать массив фигур с точками/углами, Это правда? И как он будет представлять круг или половину круга? Что же касается ориентации формы?

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

Ответ 1

Если у вас есть только эти обычные фигуры, существует простая процедура:

  • Найти контуры в изображении (изображение должно быть двоичным, как указано в вашем вопросе)
  • Приблизительно каждый контур использует функцию 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()

Ниже представлен результат:

enter image description here

Помните, что он работает только для регулярных фигур.

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

Что касается iOS, разработчики OpenCV разрабатывают некоторые образцы iOS этим летом, поэтому посетите их сайт: www.code.opencv.org и свяжитесь с ними.

Здесь вы можете найти слайды их учебника: http://code.opencv.org/svn/gsoc2012/ios/trunk/doc/CVPR2012_OpenCV4IOS_Tutorial.pdf

Ответ 2

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

Соответствие шаблонов, которое было предложено выше, хорошо работает, когда фигуры не поворачиваются или не масштабируются, и когда вокруг нет похожих фигур; другими словами, он находит лучший перевод на изображении, где находится шаблон:

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

Геометрическое хеширование - хороший способ получить инвариантность в терминах вращения и масштабирования; этот метод потребовал бы извлечения некоторых точек контура.

Обобщенный алгоритм Hough может позаботиться об инвариантности, шуме и будет иметь минимальную предварительную обработку, но это немного сложнее реализовать, чем другие методы. OpenCV имеет такие преобразования для строк и кругов.

В случае, когда количество фигур ограничено расчетными моментами или подсчет выпуклых вершин корпуса, может быть самым простым решением: структурный анализ openCV