SVD для сжатия изображений - изображение занимает больше места на диске, хмм ..? - PullRequest
1 голос
/ 12 апреля 2011
d=50;
im = imread('H:\matlab\bildanalys\terminator.gif');
M2 = double(im);
[U S V] = svd(M2);
U2 = U(:,1:d);
S2 = S(1:d,1:d);
V2 = V(:,1:d);
compressed=U2*S2*V2';
imwrite(compressed,'H:\matlab\bildanalys\compressedterminator.gif','gif')
S2

сжатое изображение в 3 раза больше ...

Я делаю svd на изображении, отбрасываю меньшие единичные значения (хотя они довольно большие), затем снова умножаю матрицы вместе, чтобы получить сжатое изображение. сжатое изображение черно-белое и больше оригинала. где я терплю неудачу?

Ответы [ 3 ]

2 голосов
/ 12 апреля 2011

Я не уверен, как вы получите в 3 раза больше, поскольку преобразования между классами масштабируются в степени 2. Единственное объяснение, которое я могу придумать, это то, что исходное изображение, im, вероятно, было uint8 с 3 цветовых канала. Это при преобразовании в оттенки серого и double становится в 1004 раз больше. Однако не похоже, что вы переходите от 3 тусклых к 1, если только вы не разместили эту часть кода здесь.

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

0 голосов
/ 25 июня 2016

Вы, вероятно, сохраняете избыточные столбцы и строки.После того, как вы усекаете диагональные значения в единственном числе, которые, конечно, сохраняете как одномерный массив, вы также должны усечь столбцы и строки матриц U и V^t до значения соответственно.В противном случае вы сохраняете набор значений, которые будут умножены на 0 во время реконструкции M = U * S * Vt.

Например, используя библиотеку Apache Commons для Java (как яменее знаком с MatLab, извините):

// compute your SVD from some input matrix
final SingularValueDecomposition svd = new SingularValueDecomposition(matrix);

// only store necessary matrix portions in memory required to compute compressed matrix
final RealMatrix u = svd.getU().getSubMatrix(0, svd.getU().getRowDimension()-1, 0, (svd.getU().getColumnDimension()-1)-compression);

// grab singular values
final RealMatrix s = svd.getS().getSubMatrix(0, (size-compression)-1, 0, (size-compression)-1);

// grab V transpose
final RealMatrix vt = svd.getVT().getSubMatrix(0, (svd.getVT().getRowDimension()-1)-compression, 0, svd.getVT().getColumnDimension()-1);

// compute compressed matrix
return new Array2DRowRealMatrix(u)
     .multiply(new Array2DRowRealMatrix(s))
     .multiply(new Array2DRowRealMatrix(vt));
0 голосов
/ 17 августа 2014

Исходная задача: A = U S V * с размерами (мксн) = (мксм) (мксн) (nxn) .

Основная идея состоит в том, чтобы использовать тонкий SVD и заменить изображение продуктами разложения U , S и V * после удаления пустого пространства компоненты, соответствующие новым нулевым значениям в SVD. Например, зонд в глубоком космосе может иметь много вычислительной мощности и небольшую полосу пропускания. Спутник записывает изображение, разлагает, сжимает и передает продукты разложения, а НЕ изображение. Изображение перекомпоновано позже.

Сжатие снижает ранг с p = min (m, n) до rho. По состоянию на п.м. отмечает, что размеры сжатого изображения одинаковы (мксн) = (мкс ро) (мкс ро) (ро xn),

Исходный ранг p может быть в тысячах, при этом rho составляет всего 10. Входная матрица имеет mn элементов; сжатые данные требуют rho (m + n + rho) элементов.

Пример: m = n = 2048, rho = 10. Для изображения требуется 4 194 304 элемента; сумма элементов в сжатой декомпозиции составляет 41 060, что составляет менее 1% от исходного объема данных.

Фактор трехкратного увеличения - это выпуск MATLAB, номер которого поставил точный диагноз.

...