Сравните изображения, чтобы найти различия - PullRequest
8 голосов
/ 31 марта 2010

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

Вопрос: Какой самый простой способ сравнить фотографии и найти различия между ними? Нужно ли мне писать свои собственные методы, или я могу использовать существующие? Было бы здорово, если бы я просто установил значение допуска (то есть изображения могут отличаться на 1%), поместите оба изображения в функцию и получите возвращаемое значение true или false:)

Инструменты: C # или VB.NET, Emgu.CV (оболочка .NET для OpenCV) или что-то подобное

Ответы [ 6 ]

3 голосов
/ 31 марта 2010

Я немного знаю об OpenCV, но немного об обработке изображений.

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

Если изображения идентичны на 100%, полученное изображение должно быть пустым. Если есть остаточные пиксели, вы можете их подсчитать и принять за меру отклонения от нормы.

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

Если у вас есть временные ограничения, вы можете захотеть уменьшить информацию в ваших изображениях перед их обработкой (используя, например, обнаружение краев и / или преобразовать их в оттенки серого или даже монохроматическое растровое изображение, если функции вашего продукта достаточно значительны) 1009 *

2 голосов
/ 01 апреля 2010

Я бы порекомендовал посмотреть AForge Imaging library , так как в нем много действительно полезных функций для этого типа работы.

Существует несколько методов, которые вы можете использовать:

  1. Простое вычитание (шаблонное изображение - текущее) и посмотрите, сколько пикселей различаются. Возможно, вы захотите ограничить результаты, т. Е. Включить только пиксели, которые отличаются на 10 или более (например).
  2. Если билеты могут перемещаться в поле обзора, то пункт 1) не сработает, если вы не сможете сначала найти билет. Например, если билет белого цвета на черном фоне, вы можете установить порог для изображения, и это даст вам хорошее представление о том, где был билет.
  3. Другой метод, который я использовал ранее, это «Поиск модели» или «Сопоставление с образцом», но я знаю только о коммерческой библиотеке Matrox Imaging Library (или MIL), которая содержит эти функции в том виде, в каком они есть нетривиально.

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

1 голос
/ 20 мая 2012

Этот парень здесь написал простой Java-код для той же проблемы. Я думаю, это будет не сложно конвертировать в C #. Он работает просто отлично, в нем также можно найти более новую и более сильную версию.

1 голос
/ 31 марта 2010

Я не эксперт в этой области, но, похоже, вам нужно что-то вроде этого

http://en.wikipedia.org/wiki/Template_matching

И, похоже, OpenCV поддерживает сопоставление с шаблоном
http://nashruddin.com/template-matching-in-opencv-with-example.html

1 голос
/ 31 марта 2010

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

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

Color color1 = Image1.GetPixel(i,j);
Color color2 = Image2.GetPIxel(i,j);
float hue1 =    color1.GetHue();
float sat1 =    color1.GetSaturation();
float bright1 = color1.GetBrightness();
float hue2 =    color2.GetHue();
float sat2 =    color2.GetSaturation();
float bright2 = color2.GetBrightness();

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


Edit:

Ради интереса я написал небольшое приложение, которое использовало мою идею выше. По сути, это было общее количество пикселей, чьи значения H, S и V отличались на некоторое количество (я выбрал 0,1 в качестве моего значения), а затем выпало из циклов сравнения, если счетчики H, S или V превышают 38400 или 2% от пиксели (0,02 *1600* 1200). В худшем случае для сравнения двух одинаковых изображений потребовалось около 2 секунд. Когда я сравнивал изображения, в которых одно было изменено настолько, чтобы превысить это значение 2%, обычно это занимало долю секунды.

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

1 голос
/ 31 марта 2010

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

...