Opencv соответствует контуру изображения - PullRequest
14 голосов
/ 24 октября 2011

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

У меня есть это изображение:

http://i55.tinypic.com/10fe1y8.jpg

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

http://i56.tinypic.com/zmxd13.jpg

(это должно быть справа)

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

Вот то, что я уже пробовал использовать opencv:

функция matchShapes - я попробовал эту функцию, используя 2 изображения в оттенках серого, и я всегда получаю один и тот же результат на каждом изображении сравнения, и значение кажется неправильным, поскольку оно равно 0,0002.

Итак, что я понял о matchShapes, но я не уверен, что это правильное предположение, что функция работает с парами контуров, а не с полными изображениями. Теперь это проблема, потому что, хотя у меня есть контуры изображений, которые я хочу сравнить, их сотни, и я не знаю, какие из них должны быть «спарены».

Поэтому я также попытался сравнить все контуры первого изображения с двумя другими с итерацией для , но я мог бы сравнить, например, контур 5 с контуром круга два опорных изображения, а не 2 контура.

Также пробовал простую функцию cv :: Compare и matchTemplate, но безуспешно.

1 Ответ

18 голосов
/ 24 октября 2011

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

Простые решения (с допущениями):

Для этих методов я предполагаю, что предоставленные вами изображения - это то, с чем вы работаете (т. Е. Объекты уже сегментированы и имеют примерно одинаковый масштаб. Кроме того, вам нужно будет исправить поворот (по крайней мере, в грубая манера.) Вы можете сделать что-то вроде итеративного поворота сравниваемого изображения каждые 10, 30, 60 или 90 градусов, или любой другой грубости, с которой, по вашему мнению, вы можете обойтись.

Например,

for(degrees = 10; degrees < 360; degrees += 10)
    coinRot = rotate(compareCoin, degrees)
    // you could also try Cosine Similarity, or even matchedTemplate here.
    metric = SAD(coinRot, targetCoin) 
    if(metric > bestMetric)
        bestMetric = metric
        coinRotation = degrees

  • Сумма абсолютных разностей (SAD) : Это позволит вам быстро сравнить изображения после определения приблизительного угла поворота.
  • Сходство косинусов : Это работает немного по-другому, обрабатывая изображение как одномерный вектор, а затем вычисляет многомерный угол между двумя векторами. Чем лучше совпадение, тем меньше будет угол.

Комплексные решения (возможно, более надежные):

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


  • Расстояние Хауссдорфа : Этот ответ даст вам представление об использовании этого метода. Это решение, вероятно, также будет нуждаться в коррекции вращения для правильной работы.
  • Преобразование Фурье-Меллина : Этот метод является расширением фазовой корреляции, которая может извлекать преобразование вращения, масштаба и преобразования (RST) между двумя изображениями.
  • Обнаружение и извлечение объектов : Этот метод включает в себя обнаружение «устойчивых» (т. Е. Инвариантов масштаба и / или вращения) изображений и сравнение их с набором целевых объектов с помощью RANSAC, LMedS или простые наименьшие квадраты. В OpenCV есть несколько примеров, использующих эту технику в matcher_simple.cpp и match_to_many_images.cpp . ПРИМЕЧАНИЕ: При использовании этого метода вы, вероятно, не захотите преобразовывать изображение в двоичную форму, поэтому доступно больше обнаруживаемых функций.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...