Main Content

# Image Compression with Low-Rank SVD

This example shows how to use `svdsketch` to compress an image. `svdsketch` uses a low-rank matrix approximation to preserve important features of the image, while filtering out less important features. As the tolerance used with `svdsketch` increases in magnitude, more features are filtered out, changing the level of detail in the image.

### Load Image

Load the image `street1.jpg`, which is a picture of a city street. The 3-D matrix that forms this image is `uint8`, so convert the image to a grayscale matrix. View the image with an annotation of the original matrix rank.

```A = imread('street1.jpg'); A = rgb2gray(A); imshow(A) title(['Original (',sprintf('Rank %d)',rank(double(A)))])``` ### Compress Image

Use `svdsketch` to calculate a low-rank matrix that approximates `A` within a tolerance of `1e-2`. Form the low-rank matrix by multiplying the SVD factors returned by `svdsketch`, convert the result to `uint8`, and view the resulting image.

```[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` produces a rank 288 approximation, which results in some minor graininess in some of the boundary lines of the image.

Now, compress the image a second time using a tolerance of `1e-1`. As the magnitude of the tolerance increases, the rank of the approximation produced by `svdsketch` generally decreases.

```[U2,S2,V2] = svdsketch(double(A),1e-1); Anew2 = uint8(U2*S2*V2'); imshow(Anew2) title(sprintf('Rank %d approximation',size(S2,1)))``` This time, `svdsketch` produces a rank 48 approximation. Most of the major aspects of the image are still visible, but the additional compression increases the blurriness.

### Limit Subspace Size

`svdsketch` adaptively determines what rank to use for the matrix sketch based on the specified tolerance. However, you can use the `MaxSubspaceDimension` name-value pair to specify the maximum subspace size that should be used to form the matrix sketch. This option can produce matrices that do not satisfy the tolerance, since the subspace you specify might be too small. In these cases, `svdsketch` returns a matrix sketch with the maximum allowed subspace size.

Use `svdsketch` with a tolerance of `1e-1` and a maximum subspace size of 15. Specify a fourth output to return the relative approximation error.

`[U3,S3,V3,apxErr] = svdsketch(double(A),1e-1,'MaxSubspaceDimension',15);`

Compare the relative approximation error of the result with the specified tolerance. `apxErr` contains one element since `svdsketch` only needs one iteration to compute the answer.

`apxErr <= 1e-1`
```ans = logical 0 ```

The result indicates that the matrix sketch does not satisfy the specified tolerance.

View the heavily compressed rank 15 image.

```Anew3 = uint8(U3*S3*V3'); imshow(Anew3) title(sprintf('Rank %d approximation',size(S3,1)))``` ### Compare Results

Finally, view all of the images side-by-side for comparison.

```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)))``` Download ebook