Вопрос по – OpenCV: сравнение простых изображений с небольшой разницей

4

У меня есть куча "простых" изображений, и я хочу сравнить, если они похожи друг на друга. Я сравниваю их друг с другом, используя сопоставление с шаблоном cv::matchTemplate) и результаты довольно хорошие.

Теперь я хочу настроить свою программу и столкнулся с проблемой. Например, у меня есть два изображения, которые очень похожи. Единственные различия, которые у них есть, состоят в том, что другая имеет более толстую линию, а цифра перед элементом отличается. Когда оба изображения маленькие, разница в одну пиксель в толщине линий приводит к большим различиям в результатах при сопоставлении с шаблоном. Когда толщина линий одинакова, а единственная разница - передняя цифра, я получаю результат сопоставления с шаблоном, например,0.98 сCV_TM_CCORR_NORMED когда совпадение успешно. Если толщина линии различна, результат сопоставления будет примерно 0,95.

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

Вот примеры изображений:

Так что у меня есть варианты?

Я пытался

расширить оригинал и шаблонerode также обаmorphologyEx Оба вычисление ключевых точек и сравнение их поиск углов

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

Любая помощь очень полезна.

Спасибо

РЕДАКТИРОВАТЬ

Вот еще несколько примеров изображений. То, что моя программа считает похожим, помещено в одну и ту же zip-папку. ZIP

Эй спасибо Я связал zip-файл, содержащий другие изображения. Я не пробовал EMD. Должен попробовать .. iiro
хорошо, но каковы неправильные классификации, чтобы я мог лучше понять проблему? Например, должны ли изображения 25.png и 47.png находиться в одной папке? В настоящее время они не. Изображения изображений 25.pgn и 29.png должны находиться в другой папке? В настоящее время они находятся в одном и том же. mmgp
Это на самом деле зависит от того, как ваши другие изображения, вы можете привести несколько более четких примеров? Это может быть тот случай, когда вам даже не нужно выполнять взаимную корреляцию, может быть достаточно простого измерения расстояния. Например, для этих двух изображений, используя нормализованное квадратное евклидово расстояние, я получаю ~ 0,44, а при использовании расстояния землеройных машин - ~ 0,02. С некоторой базовой предварительной обработкой я получаю ~ 0 с EMD и около 0,27 с первой. Проблема в том, что EMD может возвращать значения ~ 0 всем вашим изображениям, в зависимости от того, как они есть - что я понятия не имею. mmgp
25 против 47 в оптимальных ситуациях да, они должны быть в одной папке. Они извлекаются из разных исходных изображений, и поэтому они такие разные. И да, вы правильно поняли, 25 против 28 против 29. В этой папке также 54, 55, 56, которые совпадают с 25, и эти четыре должны быть в другой папке. iiro

Ваш Ответ

3   ответа
3

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

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

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

OpenCV code for thinning (Guo and Hall algo, works with CvMat inputs) The JR Parker implementation using OpenCV Possibly more efficient code here (uses OpenCV optimized access methods a lot, however most of the page is in Japanese!) And lastly a brief overview of thinning in case you're interested.
1

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

Несколько более формальным было бы взять контуры, а затем приблизительные многоугольники и сделать сравнение инвариантов (Ху Моменты так далее.)

2

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

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

enter image description here

enter image description here

Синяя линия обозначает верхний корпус, зеленая линия - нижний корпус. Если это не очевидно, когда мы рассматриваем региональные максимумы и региональные минимумы этих корпусов, мы получаем одинаковое количество в обоих из них. Кроме того, все они очень близки, за исключением некоторого смещения вy ось. Если мы рассмотрим среднееx Положение экстремумов и построение линий обоих изображений вместе мы получим на следующем рисунке. В этом случае линии синего и зеленого цвета предназначены для второго изображения, а линии красного и голубого цвета - для первого. Красные точки в среднемx координаты некоторых региональных минимумов и синие точки одинаковы, но для региональных максимумов (это наши интересы). (Следующее изображение было изменено для лучшей визуализации)

enter image description here

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

enter image description here

enter image description here

В этом случае у нас есть только 3 максимума и 3 минимума для верхнего корпуса на первом изображении, в то время как для второго - 4 максимума и 4 минимума. После вы видите графики для корпусов и достопримечательностей:

enter image description here enter image description here

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

Спасибо за анализ! Не могли бы вы указать мне правильное направление, что может быть лучшим способом извлечь верхнюю и нижнюю оболочки и рассчитать максимумы и минимумы для каждого столбца? Должен ли я просто идти столбец за столбцом или есть какие-то готовые методы в OpenCV? В OpenCV есть выпуклый метод. Может быть, я должен попробовать это в первую очередь. iiro
@iiro для извлечения верхней и нижней оболочек вы можете просто переходить от столбца к столбцу, как описано в ответе, это очень простой метод. Тогда вы можете пометить соседние точки в том жеy Координация, я реализовал это, но это очень тривиально, и я не полагался на какую-либо библиотеку (я не думаю, что кто-либо реализовал бы это). Выпуклая оболочка сильно отличается от того, что показано здесь, но, возможно, ее можно использовать и проводить анализ другим способом.
@iiro только что вспомнил одну вещь: это можно легко сделать с помощью преобразования «ударил или пропустил». Но это не доступно в OpenCV, поэтому вы должны реализовать эту часть самостоятельно (что, опять же, очень просто).

Похожие вопросы