Алгоритм сравнения изображений, игнорирующий яркость

Я ищу алгоритм, который я могу использовать для сравнения двух изображений и определения, есть ли между ними что-то существенное. Под «значительным» я имею в виду, что если вы сделаете две фотографии комнаты, и на одной из них на стене явно будет большой паук, вы сможете его обнаружить. Меня не очень интересует, ЧТО обнаруживается или даже где - просто что-то другое. Алгоритм должен будет игнорировать яркость. Если в течение дня в комнате становится светлее или темнее, алгоритм должен игнорировать это.

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

Спасибо!


person AndroidDev    schedule 21.01.2013    source источник
comment
фотографии сделаны точно с одной и той же точки? Вы пытаетесь сделать программное обеспечение для камеры безопасности?   -  person Will    schedule 21.01.2013
comment
Как насчет теней, которые со временем меняют форму? На яркость их не спишешь.   -  person Alexey Frunze    schedule 21.01.2013
comment
Да, фотографии сделаны с одного и того же места. Камера никогда не двигается. Это для приложения безопасности. Если тени настолько экстремальны, что меняют форму, то да, это тоже должно быть обнаружено.   -  person AndroidDev    schedule 21.01.2013
comment
Вы должны быть на высоте в своих вариантах использования. Паук может двигаться очень медленно, и при неправильном дизайне паук может перемещаться с одной стороны экрана на другую, оставаясь невидимым для вашей камеры.   -  person UmNyobe    schedule 21.01.2013
comment
Медленные пауки будут пойманы, если они появятся между захватами изображений. Если они могут превзойти скорость захвата, это не проблема. Я не собираюсь заполучать супермена.   -  person AndroidDev    schedule 21.01.2013
comment
@AndroidDev обратите внимание, что принятый вами ответ на самом деле не показывает, как эффективно сравнивать два разных изображения. Я думал, ты после этого?   -  person mmgp    schedule 23.01.2013


Ответы (4)


Я бы попытался выполнить высокочастотную фильтрацию ваших 2d-данных.

Согласно Фурье, каждый сигнал можно преобразовать в "частотное пространство", проанализировав, какие частоты находятся в сигнал. Это также относится к 2D-сигналам, таким как изображения.

С помощью «фильтра высоких частот» вы удаляете все низкочастотные составляющие, такие как постоянные смещения и медленные градиенты. Применительно к изображению он может служить простым алгоритмом «обнаружения краев». Глядя на образец, может быть легче понять:

Высокочастотная фильтрация изображений

Я взял изображение паука на стене откуда-то из Интернета (вверху слева). Затем я уменьшил яркость этого изображения (внизу слева). Для обеих версий я применил фильтр верхних частот с помощью GIMP (этот плагин). Для обоих входных изображений выходные данные выглядят очень похоже.

Моя рекомендация: сначала примените фильтр верхних частот, а затем посмотрите на различия.

Возможные проблемы

В соответствии с просьбой, вот некоторые проблемы, которые я могу себе представить.

  • Нет острых краев: если объект, который вы хотите обнаружить, не имеет острых краев, вы, вероятно, отфильтруете его с помощью фильтрации HF-pass. Но что это могут быть за объекты? Они должны быть огромными, плоскими (чтобы не давать теней) и неструктурированными.

  • Отличается только цвет, а не яркость: если объект отличается только своим цветом, а яркость такая же, как у фона, преобразование оттенков серого может быть проблемой. Но если вы столкнетесь с этой проблемой, просто анализируйте R, G, B-данные отдельно, то хотя бы один канал должен помочь обнаружить объект — иначе его все равно не увидеть.

Редактировать В ответ на ???, если вы также отрегулируете уровни изображения с фильтром верхних частот (которое, конечно, составляет около 0,5 * 256), просто снова нормализовав его до диапазона 0, 256 Вы получаете

С настроенными уровнями

Что, вероятно, не хуже вашего результата. Но HP-фильтры просты и при использовании БПФ очень быстры.

person Thorsten Kranz    schedule 21.01.2013
comment
блестящее использование БПФ! очень хороший подход! я бы также увеличил контрастность для лучшего разделения и, возможно, даже сделал бы фотографию в середине дня, которую затем использовал бы для нормализации яркости будущих фотографий. вычисление взаимной корреляции также может помочь в количественной оценке количества различий на двух фотографиях, если их визуальное сравнение нежелательно. - person Fredrik; 21.01.2013
comment
Я использовал БПФ в обработке звука, поэтому я с ним знаком. Никогда не думал о том, как это применимо к изображениям. Это интересный подход. Если я понимаю ваш подход, то, что вы пытаетесь сделать, это просто уменьшить все цвета до серого или белого, где белый проявляется в виде краев вдоль тех структур, которые имеют четко определенные края. Предвидите ли вы какие-либо потенциальные проблемы при использовании этого решения в определенных ситуациях? - person AndroidDev; 21.01.2013
comment
Да, вы меня правильно поняли. Ключевым моментом является сокращение информации, сохраняйте только ту информацию, которая действительно важна. Я отредактирую свой ответ, чтобы отразить некоторые возможные проблемы, с которыми вы можете столкнуться. - person Thorsten Kranz; 21.01.2013
comment
Я немного запутался в нескольких вещах. Вызывает ли фильтр верхних частот преобразование цветного изображения в оттенки серого или мне нужно сначала создать изображение в градациях серого, а затем передать его через фильтр верхних частот? Я не уверен, что даже Google для фильтра высоких частот для изображений. Я знаю, что они для звука. Можете ли вы предложить, какие алгоритмы фильтрации изображений верхних частот мне следует искать? Мне нужно написать код, поэтому плагин бесполезен. - person AndroidDev; 21.01.2013
comment
Вы сказали, что объекты, чтобы остаться незамеченными, должны быть огромными, плоскими и, возможно, без краев. Как насчет воров с большим серым гипсокартоном, расположенным между ними и камерой? Будет ли это обнаружено? - person AndroidDev; 21.01.2013
comment
Объекты, как я описал, действительно должны быть очень особенными, я думаю, вы не найдете объекты реального мира, которые достаточно редко встречаются, чтобы пройти незамеченными. По крайней мере, их края были бы видны. На какой платформе вы работаете? Твои теги мне этого не показывают, только твоё имя может быть подсказкой. - person Thorsten Kranz; 21.01.2013
comment
Фильтрация высоких частот здесь обычно применяется к 2D-данным. Таким образом, вы можете либо свести изображение к оттенкам серого, либо применить фильтр к каждому каналу отдельно, комбинируя затем результаты или анализируя их по отдельности. - person Thorsten Kranz; 21.01.2013
comment
Фурье никак не создавал фильтры верхних частот, но он сформулировал, что любой сигнал может быть построен суммой синусоидальных и косинусоидальных волн на разных частотах. Кроме того, не указано явно, какой фильтр верхних частот используется здесь, но если это что-то столь же простое, как Собеля, то маловероятно, что использование БПФ даст какой-либо выигрыш в скорости. БПФ полезен, когда у вас есть фильтры большего размера, поскольку свертка в частотной области представляет собой поточечное умножение между двумя преобразованиями Фурье. Наконец, яркость не игнорируется, поскольку этот ответ работает с цветовым пространством RGB. - person mmgp; 23.01.2013
comment
ФВЧ Фурье никак не создавал - кто это утверждал? Я использовал идею Фурье только как введение в концепцию фильтра верхних частот. Особенно для изображений, я видел, как многие коллеги были удивлены тем, что в изображении есть «частоты». Я также никогда не упоминал БПФ, который, конечно, является лишь одним из подходов к фильтрации. И наконец: да, яркость игнорируется. Первое, что делает каждый фильтр верхних частот (упрощенно): вычитает средний сигнал, так что остаются только отклонения от среднего. Таким образом, базовая яркость игнорируется. - person Thorsten Kranz; 23.01.2013
comment
@ThorstenKranz FFT - это реализация преобразования Фурье, которое является быстрым (таким образом, FFT), оно само по себе не выполняет никакой фильтрации. Вы начинаете упоминать фильтрацию верхних частот, затем без необходимости упоминаете Фурье, для меня это указывает на то, что Фурье связан с вашими высокими частотами - это не так. Фильтр верхних частот отфильтрует низкочастотные компоненты, пожалуйста, не добавляйте еще больше путаницы в список. Если ваша яркость уменьшена так, что край больше не дает высоких частот, он будет отфильтрован. Итак, как вы можете утверждать, что яркость игнорируется? - person mmgp; 23.01.2013
comment
Вы когда-нибудь действительно использовали частотный фильтр? Вы когда-нибудь сравнивали фильтрованный и нефильтрованный сигнал? - person Thorsten Kranz; 23.01.2013
comment
@ThorstenKranz Вы хотите знать, как это делается, или у вас есть актуальный вопрос? Реализуйте любой базовый фильтр верхних частот, например тот, который дал Собел, и примените его самостоятельно, не полагаясь на GIMP. - person mmgp; 24.01.2013
comment
Это был не реальный вопрос, а скорее риторический, ставящий под сомнение ваш практический опыт в области обработки и анализа сигналов. - person Thorsten Kranz; 24.01.2013

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

Вычтите соответствующее среднее значение изображения (среднее значение пикселя) из всех пикселей каждого изображения и возьмите разницу. Это позаботится о яркости.

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

person Adi Shavit    schedule 21.01.2013
comment
Это своего рода подход, который я уже пробовал. Однако я брал RGB как одно значение (например, 0xaabbcc) и нормализовал изображение на основе вычитания этих значений. Оказывается, дисперсия очень непостоянна, когда цвета находятся дальше друг от друга. Я думаю, мне нужно добавить значения RGB и использовать их вместо этого. Я не понял ваш последний абзац о том, как учитывать контраст. Можете ли вы привести простой пример изображения размером 4x4 пикселя? Спасибо! - person AndroidDev; 21.01.2013

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

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

Каждый раз, когда ваша камера делает снимок (называемый «pic»), вы должны:

  • Sum up absolute pixels value differences between "avg" and "pic".
    • If above a threshold, something is moving in front of the camera.
    • В противном случае измените «avg», чтобы оно немного совпадало с «pic». Вы должны найти правильную формулу, например, avg = avg * 0.95 + pic * 0.05.

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

person Nicolas Repiquet    schedule 21.01.2013
comment
Проблема с этим подходом заключается в том, что когда вы начинаете полагаться на средние значения, даже небольшой, но действительный объект на изображении, которого не должно быть, может практически не повлиять на общее значение, потому что другие части изображения могут измениться из-за солнечного света. (или тени) и противостоять наличию недопустимого объекта. Даже если солнечный свет оказывает незначительное влияние, он суммируется при усреднении. Я считаю, что необходимо учитывать яркость каждого пикселя или, как предложил Торстен Кранц, вообще убрать яркость. - person AndroidDev; 21.01.2013
comment
@AndroidDev Ну, тени будут создавать движущиеся края и обнаруживаться как движущиеся объекты, если вы со временем не измените свое эталонное изображение. Перефразируя, вам нужен какой-то способ обнаруживать быстро движущиеся объекты и игнорировать медленно движущиеся. - person Nicolas Repiquet; 21.01.2013

Как насчет удаления компонента яркости из пикселей:

Red_ratio = Red / (Red + Blue + Green)
Blue_ratio = Blue / (Red + Blue + Green)
Green_ratio = Green / (Red + Blue + Green)
person user5792628    schedule 20.06.2016