#image #compression #octave #eigenvalue
#изображение #сжатие #октава #собственное значение
Вопрос:
Я хочу сжать изображение, используя собственные значения и eigenvector, поскольку я уже сделал это, используя разложение по сингулярным значениям, но я делаю что-то неправильно, пытаясь сжать его, используя собственные значения и собственные векторы.
Вот некоторый код, чтобы увидеть, что я уже пробовал, но что-то пошло не так при попытке вычислить Z
матрицу.
image_matrix = double(imread(image));
[m n] = size(image_matrix);
miu = zeros(m, 1);
A = [];
for i = 1 : m
miu(i) = mean(image_matrix(i, :));
A(i, :) = image_matrix(i, :) - miu(i);
endfor
Z = A*A'/(n - 1);
[V S] = eig(Z);
W = V(:, 1 : k);
Y = W'*A;
A_k = W*Y miu;
W*Y miu
должно было дать мне приближение матрицы A из приведенного выше, но это просто дает пустое изображение. Приведенный выше код получает: путь к изображению и число, k
такое k
, которое представляет собой некоторый порядок приближения… Я вызываю это с помощью ('path/to/image', 2)
и не получаю ожидаемого результата. Также я использую это только для черно-белых изображений.
Комментарии:
1. @CrisLuengo Ваша ставка неверна! Это не так,
A
матрица, я думаю, является хорошей средней матрицейimage_matrix
.2. Да, я отображаю изображение, например
imshow(uint8(A_k));
, я обновляю каждую строку вычитанием между каждой строкой и средним значением строки, потому что таков был алгоритм, также я попытался удалить его, и все еще ничего3. Две вещи: 1: вы не используете
S
собственные значения. 2. Вы сохраняете собственные векторы для наименьших собственных значений. В справке Octave указано, что собственные значения не упорядочены, но я вижу, что они упорядочены от наименьшего к наибольшему.4. Вы должны отображать с помощью
imshow(A_k,[])
.5. @CrisLuengo В чем смысл упорядоченных собственных значений и что мне с этим делать? и также я отобразил его таким образом, оно больше не пустое, но и не является правильным изображением
Ответ №1:
То, что вы пытаетесь сделать, это найти значимые режимы корреляционной матрицы вашего изображения, то есть режимы, которые имеют наибольшие собственные значения. В общем случае eig возвращает собственные значения / векторы в случайном порядке, @CrisLuengo сообщает вам, что прежде чем выбрасывать собственные значения / режимы, вам нужно сначала упорядочить результаты, которые возвращает eig, как я сделал в этом скрипте;
clear;clf
tx = ty = linspace (-8, 8, 41)';
[xx, yy] = meshgrid (tx, ty);
r = sqrt (xx .^ 2 yy .^ 2) eps;
tz = sin (r) ./ r;
%mesh (tx, ty, tz);
Z=tz*transpose(tz);
[vec,L]=eig(Z);
lambda=diag(L);
[lambda,order]=sort(lambda,'descend');
vec=vec(:,order);
%%plot(lambda);hold on;plot(diag(L))
%% reconstruct with 5 largest modes:
neof=5;
shortz=tz*vec(:,1:5)*transpose(vec(:,1:5));
mesh (tx, ty, shortz);
Изображение имеет размер sin (r) / r в сетке 41 на 41. Если вы нанесете на график diag(L), (неупорядоченные) собственные значения, вы заметите, что 30 или около того приближаются к нулю, что означает, что они соответствуют очень, очень небольшой информации. Все действия выполняются в последних нескольких режимах. После изменения порядка они становятся первыми несколькими режимами.