2012-01-09 6 views
4

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

Мой текущий подход:

  1. Обнаружение контуров
  2. Для каждого контура, рассчитать максимальный ограничивающий параллелепипед
  3. матч каждый ограничивающий параллелепипед с одной из известных форм в отдельности. В моем реальном проекте я масштабирую область до размера шаблона и вычисляя различия в градиенте Sobel, но для этой демонстрации я просто использую соотношение сторон.

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

Есть ли способ изменить мой подход для обработки смежных форм отдельно? Кроме того, есть ли лучший способ выполнить шаг 3?

Например: (Es зеленого цвета, Ys синего цвета)

enter image description here

Failed случай: (неизвестная форма в красном цвете)

enter image description here

Исходный код:

import cv 
import sys 
E = cv.LoadImage('e.png') 
E_ratio = float(E.width)/E.height 
Y = cv.LoadImage('y.png') 
Y_ratio = float(Y.width)/Y.height 
EPSILON = 0.1 

im = cv.LoadImage(sys.argv[1], cv.CV_LOAD_IMAGE_GRAYSCALE) 
storage = cv.CreateMemStorage(0) 
seq = cv.FindContours(im, storage, cv.CV_RETR_EXTERNAL, 
     cv.CV_CHAIN_APPROX_SIMPLE) 
regions = [] 
while seq: 
    pts = [ pt for pt in seq ] 
    x, y = zip(*pts)  
    min_x, min_y = min(x), min(y) 
    width, height = max(x) - min_x + 1, max(y) - min_y + 1 
    regions.append((min_x, min_y, width, height)) 
    seq = seq.h_next() 

rgb = cv.LoadImage(sys.argv[1], cv.CV_LOAD_IMAGE_COLOR) 
for x,y,width,height in regions: 
    pt1 = x,y 
    pt2 = x+width,y+height 
    if abs(float(width)/height - E_ratio) < EPSILON: 
     color = (0,255,0,0) 
    elif abs(float(width)/height - Y_ratio) < EPSILON: 
     color = (255,0,0,0) 
    else: 
     color = (0,0,255,0) 
    cv.Rectangle(rgb, pt1, pt2, color, 2) 

cv.ShowImage('rgb', rgb) 
cv.WaitKey(0) 

e.png:

enter image description here

y.png:

enter image description here

хорошо:

enter image description here

плохо:

enter image description here

Прежде чем кто-нибудь спросит, нет, я не пытается сломать captcha :) OCR само по себе на самом деле не так актуально: фактические фигуры в моем реальном проекте не являются персонажами - я просто ленивый, а символы - это самая легкая вещь для рисования (и до сих пор обнаруживается тривиальными методами).

+0

Рассматривались ли вы для определения допустимого интервала для отношения высоты/ширины. Если все случаи, когда фигуры касаются друг друга, приводят к слишком широким или слишком высоким ограничивающим прямоугольникам, может быть ключом. –

+0

Да, я об этом уже подумал. Спасибо, что упомянул об этом. – misha

ответ

3

Поскольку ваши фигуры могут различаться по размеру и соотношению, вы должны посмотреть на масштабирующие инвариантные дескрипторы. Буква таких дескрипторов была бы идеальна для вашего приложения.

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

Я использовал моменты Зернике и Ху в прошлом, последний из которых был самым известным.Пример реализации здесь можно найти здесь: http://www.lengrand.fr/2011/11/classification-hu-and-zernike-moments-matlab/.

Другое: учитывая вашу проблему, вы должны посмотреть на технологии OCR (означает оптическое распознавание символов: http://en.wikipedia.org/wiki/Optical_character_recognition;)).

Надеюсь, это поможет.

Julien

+0

Спасибо за ваш комментарий. Вы бы подсчитали моменты для каждого контура? Если да, то как бы решить проблему слияния фигур? Выделенные моменты на самом деле не соответствовали бы моментам тренированной формы, не так ли? Кроме того, OCR * per se * здесь не очень уместен: фактические фигуры в моем реальном проекте не являются персонажами - я просто ленив, а персонажи - это самая простая вещь для рисования (и до сих пор обнаруживаются тривиальными методами) , Поскольку вы, вероятно, не первый или последний человек, которые думают о OCR, когда смотрели на вопрос, я добавил к нему немного. – misha

+0

Вы уже пробовали методы корреляции формы? – jlengrand

+0

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

0

Вы попробуйте Фаску Matching или согласование контура (заочный), используя CCH дескриптора.

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

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

Смежные вопросы