Изображение контура совпадения

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

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

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

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

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

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

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

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

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

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

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

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

Ответы

Ответ 1

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

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

Для этих методов я предполагаю, что ваши изображения, которые вы предоставили, - это то, с чем вы работаете (т.е. объекты уже сегментированы и примерно одинаковы. Кроме того, вам нужно будет скорректировать поворот (по крайней мере, в грубый способ). Вы можете сделать что-то вроде итеративного поворота сравнительного изображения каждые 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): Это позволит вам быстро сравнивать изображения, как только вы определили приблизительный угол поворота.
  • сходство с косинусом: это работает немного по-другому, обрабатывая изображение как 1D-вектор, а затем вычисляет размерный угол между два вектора. Чем лучше совпадение, тем меньше будет угол.

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

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


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