Подтвердить что ты не робот

Сравнение двух гистограмм

Для небольшого проекта мне нужно сравнить одно изображение с другим - определить, являются ли изображения примерно одинаковыми или нет. Изображения малы, варьируются от 25 до 100 пикселей. Изображения предназначены для одинаковых данных изображения, но являются сублимированными, поэтому простая проверка равенства пикселей не будет работать. Рассмотрим эти два возможных сценария:

  • Камера наблюдения (CCTV) в музее, смотрящая на выставку: мы хотим быстро увидеть, показывают ли две разные видеорамки одну и ту же сцену, но небольшие различия в освещении и фокусировке камеры означают, что они не будут идентичными.
  • Изображение векторного графического интерфейса компьютера, отображаемого на 64x64, по сравнению с тем же значком, отображаемым на 48x48 (но оба изображения будут уменьшены до 32x32, чтобы гистограммы имели одинаковое общее количество пикселей).

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

Скажем, у меня эти три гистограммы, которые представляют собой краткий красный канал RGB для трех изображений (для простоты 5-битных изображений для 7-пиксельных изображений):

H1            H2            H3 

  X           X                     X
  X   X       X       X             X
X X   X X     X X   X X     X X X X X
0 1 2 3 4     0 1 2 3 4     0 1 2 3 4

H1 = [ 1, 3, 0, 2, 1 ]
H2 = [ 3, 1, 0, 1, 2 ]
H3 = [ 1, 1, 1, 1, 3 ] 

Изображение 1 (H1) - это мое ссылочное изображение, и я хочу посмотреть, похоже ли изображение 2 (H2) и/или изображение 3 (H3) на изображение 1. Обратите внимание, что в этом примере, Изображение 2 аналогично изображению 1, но изображение 3 не является.

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

Чтобы продемонстрировать проблему с этим подходом, в коде С#, например:

Int32[] image1RedHistogram = new Int32[] { 1, 3, 0, 2, 1 };
Int32[] image2RedHistogram = new Int32[] { 3, 2, 0, 1, 2 };
Int32[] image3RedHistogram = new Int32[] { 1, 1, 1, 1, 3 };

Int32 GetDifference(Int32[] x, Int32[] y) {
    Int32 sumOfDifference = 0;
    for( int i = 0; i < x.Length; i++ ) {
        sumOfDifference += Math.Abs( x[i] - y[i] );
    }
    return sumOfDifferences;
}

Выходной сигнал которого:

GetDifference( image1RedHistogram, image2RedHistogram ) == 6
GetDifference( image1RedHistogram, image3RedHistogram ) == 6

Это неверно.

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

4b9b3361

Ответ 1

Сравнение гистограмм само по себе само по себе.

У вас есть два больших класса функций сравнения: сравнение bin-to-bin и сравнение с двумя ячейками.

  • Сравнение Bin-to-bin: как вы сказали, стандартная сумма различий довольно плохая. Там улучшается расстояние между квадратами, которое говорит, что если H1.red[0] = 0.001 and H2.red[0] = 0.011 гораздо важнее, чем if H1.red[0] = 0.1 and H2.red[0] = 0.11, хотя в обоих случаях |H1.red[0] - H2.red[0]| = 0.01.
  • Сравнение с перекрестием: стандартный пример, называемый матрицей сходства битов, требует некоторой матрицы подобия M, где в M(i,j) - сходство между ячейками я и j. Предположим, что bin[i] красный. Если bin[j] темно-красный, то M(i,j) большой. Если bin[j] зеленый, M(i,j) невелик. Тогда расстояние между гистограммами H1 и H2 будет sqrt((H1-H2)*M*(H1-H2)). Этот метод учитывает то, что вы сказали о "близких" бункерах! Расстояние перемещения Земли (EMD) - это еще один вид расстояния между ячейками.

Чтобы закончить, у меня есть три момента:

  • Вы должны прочитать эту статью на расстоянии гистограммы. Это довольно просто и вводит вас на расстояния гистограммы. Все расстояния, о которых я говорил, хорошо подведены в главе 1. Честно говоря, последнее, что описано в этой статье, не настолько сложное, но, вероятно, это может быть излишним для вашего дела.
  • Расстояние между бинами очень хорошее, но может быть дорогостоящим (т.е. долгим для вычисления, поскольку оно включает в себя матрицу, таким образом, O (n ^ 2)). Самый простой способ обойти дорогостоящее вычисление перекрестного бина (и это широко сделано) - это сделать небольшое мягкое назначение: если пиксель красный, тогда вы должны заполнить ВСЕ ячейки, которые удаленно выглядят как красные (конечно, давая больше вес к самым близким цветам). Затем вы можете использовать алгоритм bin-to-bin.
  • Немного больше математически-ориентированного: предыдущий момент заключался в сокращении сравнения между бинами и сопоставлением бин-к-бин. Фактически, он состоит из неявной диагонализации матрицы подобия M. Если вы можете диагонализировать M = P'*D*P, где P' является транспонированием P, тогда sqrt((H1-H2)'*M*(H1-H2)) = sqrt((H1-H2)'*P'*D*P*(H1-H2)) = sqrt((P(H1-H2))'*D*(P(H1-H2))). В зависимости от того, насколько тривиально вам вычислить P(H1-H2), это может сэкономить время вычислений. Интуитивно, если H1 является вашей исходной гистограммой, P*H1 является мягким назначением, и вы используете неявную матрицу подобия M = P'*Id*P

Ответ 2

Я удивлен, что никто не упомянул о реализации сравнения гистограммы в opencv и может легко обрабатывать многоканальные изображения (оттенки серого, rgb, rgba и т.д.) разного формата (uchar, float, double и т.д.)

Включает расстояние Бхаттачарьи, Чи-квадрат, методы корреляции и пересечения. Вы можете найти

compareHist(InputArray H1, InputArray H2, int method)

в руководстве здесь.

Ответ 3

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

В вашем примере перемещение 5 единиц с красного [0] на красный 1 будет стоить (c*1*5) при перемещении 5 единиц от красного [0] до красного [10 ] будет стоить (c*10*5).

Существует несколько реализаций. FastEMD имеет код в С++, Java и Matlab. Я считаю, что OpenCV имеет определенную поддержку.

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

Ответ 4

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

1/(MN) SUM_i [((Mni - Nmi) ^ 2)/(mi + ni)].

M и N - общее количество записей в каждой гистограмме, mi - количество записей в бине я гистограммы M, а ni - количество записей в bin я гистограммы N.

Еще одно испытание - испытание Колмогорова-Смирнова. В этом тесте рассматривается максимальная разница между кумулятивными распределениями вероятности двух гистограмм. Это сложнее реализовать, я думаю, что числовые рецепты в C имеют фрагмент кода в C, и я уверен, что это в Matlab. Если вы больше заинтересованы в различии, это форма гистограммы и не столько точные значения, которые могут быть лучшим тестом, но и непараметрическим.

Ответ 5

В основном вы хотите посмотреть вероятностные расстояния. Их много, и вам нужно решить, что подходит для вашего приложения. В последнее время мне повезло с Чи-квадратом и Кулбаком-Лейблером.

Ответ 6

Нормализовать гистограммы, разделив значение в каждом бункере на входящей гистограмме на общее количество пикселей, на которых основана гистограмма. Затем используйте @tkerwin EMD.

Ответ 7

Я думаю, что EMD - хорошее решение для решения проблемы перекрестного бина, сравнивается с методом bin to bin. Однако, как утверждают некоторые, EMD очень долгое время. Не могли бы вы предложить мне другой подход для перекрестного бина?

Ответ 8

Как отмечали другие, вероятно, оптимальным решением является расстояние от Земли или EMD (он же показатель Вассерштейна). Метод Shortlist для быстрого вычисления EMD доступен в пакете R, transport. Он был представлен в документе с 2014 года, сравнивая его с другими методами, демонстрируя более быстрое время вычислений. Единственный недостаток заключается в том, что он в R, который не является быстрым, если не запрограммирован на С++ под капотом.