Main Content

La traducción de esta página está obsoleta. Haga clic aquí para ver la última versión en inglés.

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)))

Consulte también

| |

Temas relacionados