Взаимная информация и совместная энтропия двух изображений-MATLAB
у меня есть два черно-белых изображения, и мне нужно рассчитать взаимную информацию.
Image 1 = X
Image 2 = Y
Я знаю, что взаимная информация может быть определена как:
MI = entropy(X) + entropy(Y) - JointEntropy(X,Y)
MATLAB уже имеет встроенные функции для вычисления энтропии, но не для вычисления совместной энтропии. Я думаю, истинный вопрос: Как вычислить совместную энтропию двух изображений?
вот пример изображений, которые я хотел бы найти совместную энтропию:
X =
0 0 0 0 0 0
0 0 1 1 0 0
0 0 1 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0
Y =
0 0 0 0 0 0
0 0 0.38 0.82 0.38 0.04
0 0 0.32 0.82 0.68 0.17
0 0 0.04 0.14 0.11 0
0 0 0 0 0 0
1 ответов
чтобы вычислить совместную энтропию, вам нужно вычислить совместную гистограмму между двумя изображениями. Совместная гистограмма по существу такая же, как нормальная 1D гистограмма, но интенсивность первого измерения регистрируется для первого изображения, а интенсивность второго измерения регистрируется для второго изображения. Это очень похоже на то, что обычно называют матрица совпадений. На месте (i,j)
в совместной гистограмме, она говорит вам сколько значений интенсивности мы имеем встречались, которые имеют интенсивность i
в первом изображении и интенсивности j
на втором изображении.
важно то, что эти журналы, сколько раз мы видели эту пару интенсивностей в тех же соответствующих местах. Например, если у нас есть совместное количество гистограмм (7,3) = 2
, это означает, что, когда мы сканировали оба изображения, когда мы столкнулись с интенсивностью 7
, на таком же соответствуя положении в втором изображении, мы столкнулся с интенсивностью 3
в общей сложности 2
раза.
построение совместной гистограммы очень просто.
- во-первых, создать
256 x 256
matrix (предполагая, что ваше изображение является 8-разрядным целым числом без знака) и инициализирует их до всех нулей. Кроме того, вам нужно убедиться, что оба ваших изображения имеют одинаковый размер (ширина и высота). - как только вы это сделаете, взгляните на первый пиксель каждого изображения, который мы обозначим как верхний левый угол. В частности, взгляните на интенсивности для первого и второго изображения в этом месте. Интенсивность первого изображения будет служить строкой, а интенсивность второго изображения будет служить столбцом.
- найдите это место в Матрице и увеличьте это место в матрице на
1
. - повторите это для остальных местоположений на вашем изображении.
- после того, как вы закончите, разделите все записи на общее количество элементов в любом изображении (помните, что они должны быть одинакового размера). Это даст нам совместное распределение вероятностей между обоими изображениями.
можно было бы сделать это с for
петли, но, как известно, for
петли, как известно, медленно и следует избегать, если это вообще возможно. Однако, вы можете легко сделать это в MATLAB следующим образом без петли. Предположим, что im1
и im2
первые и вторые изображения вы хотите сравнить. Что мы можем сделать, это преобразовать im1
и im2
в векторы. Затем мы можем использовать accumarray
чтобы помочь нам вычислить совместные гистограммы. accumarray
является одной из самых мощных функций в MATLAB. Вы можете думать об этом как о миниатюрной парадигме MapReduce. Проще говоря, каждый ввод данных имеет ключ и связанное с ним значение. Цель accumarray
- это привязка всех значений, принадлежащих одному ключу, и выполнение некоторых операций над всеми этими значениями. В нашем случае ключ "" были бы значения интенсивности, а сами значения являются значением 1
для каждого значения интенсивности. Мы бы тогда хотели добавить все значения 1
эта карта в тот же Бин, и именно так мы вычисляем гистограмму. Поведение по умолчанию для accumarray
добавить все эти значения. В частности, вывод accumarray
будет массивом, в котором каждая позиция вычисляет сумму всех значений, сопоставленных этому ключу. Например, первая позиция будет суммированием всех значений, сопоставленных ключу 1, вторая позиция будет суммированием всех значений, сопоставленных ключу 2 и так далее.
однако для совместной гистограммы вы хотите выяснить, какие значения соответствуют одной и той же паре интенсивности (i,j)
, и поэтому ключи здесь будут парой 2D-координат. Таким образом, любые интенсивности, которые имеют интенсивность i
на первом изображении и j
на второй картинке в том же пространстве местоположение shared между двумя изображениями перейти к тому же ключу. Поэтому в 2D-случае вывод accumarray
будет 2D-матрицей, где каждый элемент (i,j)
содержит суммирование всех значений, сопоставленных с key (i,j)
, подобно случаю 1D, который был упомянут ранее, что именно то, что мы после.
другими словами:
indrow = double(im1(:)) + 1;
indcol = double(im2(:)) + 1; %// Should be the same size as indrow
jointHistogram = accumarray([indrow indcol], 1);
jointProb = jointHistogram / numel(indrow);
с accumarray
, первый вход ключи и второй входных значений. Записка с accumarray
is что если каждый ключ имеет то же самое значение, вы можете просто назначить константу второму входу, что я и сделал, и это 1
. В общем случае это массив с тем же количеством строк, что и первый вход. Кроме того, обратите особое внимание на первые две строки. Неизбежно будет интенсивность 0
на вашем изображении, но потому что MATLAB начинает индексировать на 1
, нам нужно компенсировать оба массива на 1
.
теперь, когда у нас есть совместная гистограмма, вычислить общую энтропию очень просто. Это похоже на энтропию в 1D, за исключением того, что теперь мы просто суммируем всю совместную вероятностную матрицу. Имейте в виду, что очень вероятно, что ваша совместная гистограмма будет иметь много 0
записи. Нам нужно убедиться, что мы пропустим те или log2
операция будет неопределенной. Давайте избавимся от любых нулевых записей сейчас:
indNoZero = jointHistogram ~= 0;
jointProb1DNoZero = jointProb(indNoZero);
обратите внимание, что я искал гистограмму сустава вместо сустава вероятностная матрица. Это связано с тем, что совместная гистограмма состоит из целых чисел, а матрица совместной вероятности будет лежать между 0
и 1
. Из-за деления я хочу избежать сравнения любых записей в этой матрице с 0
из-за численного округления и нестабильности. Вышеизложенное также преобразует нашу совместную матрицу вероятностей в штабелированный 1D-вектор, что нормально.
таким образом, совместная энтропия может быть вычислена как:
jointEntropy = -sum(jointProb1DNoZero.*log2(jointProb1DNoZero));
если мой понимание вычисления энтропии для изображения в MATLAB является правильным, оно должно вычислять гистограмму / распределение вероятности по 256
бункеры, поэтому вы можете использовать эту функцию здесь с совместной энтропией, которая только что была вычислена.
что, если вместо этого у нас есть данные с плавающей запятой?
до сих пор мы предполагали, что изображения, с которыми вы имели дело, имеют интенсивности, которые являются целочисленными. Что если у нас есть данные с плавающей запятой? accumarray
предполагает то, что вы пытаетесь индексировать в выходной массив, используя целые числа, но мы все еще можем достичь того, что мы хотим с этим небольшим бугром на дороге. Что бы вы сделали, это просто назначить каждое значение с плавающей запятой в обоих изображениях, чтобы иметь уникальный ID. Таким образом, вы бы использовали accumarray
С этими идентификаторами вместо этого. Чтобы облегчить назначение этого идентификатора, используйте unique
- в частности, третий выход из функции. Вы бы взяли каждый из изображений, поместить их в unique
и сделайте эти индексы входными в accumarray
. Другими словами, сделайте это вместо этого:
[~,~,indrow] = unique(im1(:)); %// Change here
[~,~,indcol] = unique(im2(:)); %// Change here
%// Same code
jointHistogram = accumarray([indrow indcol], 1);
jointProb = jointHistogram / numel(indrow);
indNoZero = jointHistogram ~= 0;
jointProb1DNoZero = jointProb(indNoZero);
jointEntropy = -sum(jointProb1DNoZero.*log2(jointProb1DNoZero));
обратите внимание, что с indrow
и indcol
, мы непосредственно назначаем третий выход unique
к этим переменным, а затем с использованием того же совместного кода энтропии, который мы вычисляли ранее. Нам также не нужно смещать переменные на 1, Как мы делали ранее, потому что unique
назначит идентификаторы начиная с 1.
в сторону
вы фактически можно рассчитать гистограммы или распределения вероятностей для каждого изображения отдельно, используя совместную матрицу вероятностей. Если вы хотите рассчитать гистограммы / распределения вероятностей для первого изображения, вы просто накапливаете все столбцы для каждой строки. Чтобы сделать это для второго изображения, вы просто накапливаете все строки для каждого столбца. Таким образом, вы можете сделать:
histogramImage1 = sum(jointHistogram, 1);
histogramImage2 = sum(jointHistogram, 2);
после этого вы можете вычислить энтропию обоих из них самостоятельно. К дважды проверьте, убедитесь, что вы превратили оба из них в PDF-файлы, а затем вычислите энтропию, используя стандартное уравнение (как указано выше).
как мне, наконец, вычислить взаимную информацию?
чтобы, наконец, вычислить взаимную информацию, вам понадобится энтропия двух изображений. Вы можете использовать встроенный MATLAB entropy
функция, но это предполагает, что существует 256 уникальных уровней. Вы, вероятно, хотите применить это для случая, когда N
различные уровни вместо 256, и поэтому вы можете использовать то, что мы сделали выше, с совместной гистограммой, затем вычисляя гистограммы для каждого изображения в указанном выше коде, а затем вычисляя энтропию для каждого изображения. Вы просто повторите расчет энтропии, который использовался совместно, но примените его к каждому изображению индивидуально:
%// Find non-zero elements for first image's histogram
indNoZero = histogramImage1 ~= 0;
%// Extract them out and get the probabilities
prob1NoZero = histogramImage1(indNoZero);
prob1NoZero = prob1NoZero / sum(prob1NoZero);
%// Compute the entropy
entropy1 = -sum(prob1NoZero.*log2(prob1NoZero));
%// Repeat for the second image
indNoZero = histogramImage2 ~= 0;
prob2NoZero = histogramImage2(indNoZero);
prob2NoZero = prob2NoZero / sum(prob2NoZero);
entropy2 = -sum(prob2NoZero.*log2(prob2NoZero));
%// Now compute mutual information
mutualInformation = entropy1 + entropy2 - jointEntropy;
надеюсь, что это помогает!