Compresión de imágenes con SVD de rango bajo
Este ejemplo muestra cómo utilizar svdsketch
para comprimir una imagen. svdsketch
utiliza una aproximación de matriz de rango bajo para conservar las funcionalidades importantes de la imagen, mientras se filtran las funcionalidades menos importantes. A medida que aumenta la magnitud de la tolerancia utilizada con svdsketch
, se filtran más funcionalidades, cambiando el nivel de detalle de la imagen.
Cargar imagen
Cargue la imagen street1.jpg
, que es una foto de una calle en una ciudad. La matriz 3D que forma esta imagen es uint8
, así que convierta la imagen a una matriz de escala de grises. Vea la imagen con una anotación del rango de la matriz original.
A = imread('street1.jpg'); A = rgb2gray(A); imshow(A) title(['Original (',sprintf('Rank %d)',rank(double(A)))])
Comprimir imagen
Utilice svdsketch
para calcular una matriz de rango bajo que se aproxime a A
en una tolerancia de 1e-2
. Forme la matriz de rango bajo multiplicando los factores de SVD devueltos por svdsketch
, convierta el resultado a uint8
y vea la imagen resultante.
[U1,S1,V1] = svdsketch(double(A),1e-2);
Anew1 = uint8(U1*S1*V1');
imshow(uint8(Anew1))
title(sprintf('Rank %d approximation',size(S1,1)))
svdsketch
produce una aproximación de rango 288, que da como resultado cierta granularidad menor en algunos de los límites de la imagen.
Ahora, comprima la imagen una segunda vez utilizando la tolerancia de 1e-1
. A medida que aumenta la magnitud de la tolerancia, el rango de la aproximación producida por svdsketch
generalmente se reduce.
[U2,S2,V2] = svdsketch(double(A),1e-1);
Anew2 = uint8(U2*S2*V2');
imshow(Anew2)
title(sprintf('Rank %d approximation',size(S2,1)))
Esta vez, svdsketch
produce una aproximación de rango 48. La mayoría de los aspectos importantes de la imagen sigue siendo visible, pero la compresión adicional aumenta el desenfoque.
Limitar el tamaño del subespacio
svdsketch
determina de forma adaptativa qué rango utilizar para la aproximación de la matriz en función de la tolerancia especificada. Sin embargo, puede utilizar el par nombre-valor MaxSubspaceDimension
para especificar el tamaño máximo del subespacio que se debería utilizar para formar la aproximación de la matriz. Esta opción puede producir matrices que no satisfagan la tolerancia, ya que puede que el subespacio que especifica sea demasiado pequeño. En estos casos, svdsketch
devuelve una aproximación de la matriz con el tamaño de subespacio máximo permitido.
Utilice svdsketch
con una tolerancia de 1e-1
y un tamaño máximo del subespacio de 15. Especifique una cuarta salida para devolver el error de aproximación relativo.
[U3,S3,V3,apxErr] = svdsketch(double(A),1e-1,'MaxSubspaceDimension',15);
Compare el error de aproximación relativo del resultado con la tolerancia especificada. apxErr
contiene un elemento ya que svdsketch
solo necesita una iteración para calcular esta respuesta.
apxErr <= 1e-1
ans = logical
0
El resultado indica que la aproximación de la matriz no satisface la tolerancia especificada.
Vea la imagen de rango 15 muy comprimida.
Anew3 = uint8(U3*S3*V3');
imshow(Anew3)
title(sprintf('Rank %d approximation',size(S3,1)))
Comparar resultados
Finalmente, vea todas las imágenes una al lado de la otra para compararlas.
tiledlayout(2,2,'TileSpacing','Compact') nexttile imshow(A) title('Original') nexttile imshow(Anew1) title(sprintf('Rank %d approximation',size(S1,1))) nexttile imshow(Anew2) title(sprintf('Rank %d approximation',size(S2,1))) nexttile imshow(Anew3) title(sprintf('Rank %d approximation',size(S3,1)))