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

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

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

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

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

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

3 ответа

Решение

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

  1. Найти контуры на изображении (изображение должно быть двоичным, как указано в вашем вопросе)
  2. Приблизьте каждый контур, используя approxPolyDP функция.
  3. Сначала проверьте количество элементов в приближенных контурах всех фигур. Это признать форму. Например, у квадрата будет 4, у пятиугольника - 5. У кругов будет больше, я не знаю, поэтому мы его находим. (Я получил 16 за круг и 9 за полукруг.)
  4. Теперь назначьте цвет, запустите код для вашего тестового изображения, проверьте его номер, залейте его соответствующими цветами.

Ниже приведен мой пример на 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

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

Другие вопросы по тегам