In-Class Work, Tuesday December 7
SVD for image compression
Math 221 Linear Algebra, Fall 2021
December 7, 2021

T. Ratliff, Wheaton College
ratliff_thomas@wheatoncollege.edu

Loading an image and converting to grayscale

These are the Mathematica commands to import an image, 
convert it to grayscale, and 
place the numeric code for each pixel in a matrix aGray.

image1 =Import["https://tratliff.webspace.wheatoncollege.edu/2021_Fall/math221/local/boston_public_market_08_21.jpeg"]
image1Gray = ColorConvert[image1,"Grayscale"]
aGray= N[ImageData[image1Gray,"Byte"]];

Let’s compare the dimensions

ImageDimensions[image1Gray]
Dimensions[aGray]

It’s kind of annoying that these are in different orders, but the image dimensions are width x height, whereas the matrix is rows x columns.

Looking at the singular values

Load the singular values of aGray into a list, see how long the list is, and then look at the first 50 singular values.

sVals=SingularValueList[aGray];
Length[sVals]
sVals[[1;;50]]

They sure start big, (Subscript[σ, 1]) = 90,440 but then start to get smaller quickly. 
Let’s plot the first 200 singular values.

ListPlot[sVals[[1;;200]]]

These seem to drop pretty quickly from over 90,000 to under 1000 by the time we hit the 100th singular value.

A singular value decomposition using the largest 100 singular values

Rather than taking the entire singular value decomposition, let’s look at the singular value decomposition with the 100 largest singular values, and see what the resulting image looks like. 

The Image[aGraySVG/256] will convert the array back to the image format that is pleasing to Mathematica.

{aGu, aGs, aGv} = SingularValueDecomposition[aGray,100];
aGraySVG = aGu.aGs.Transpose[aGv];
Image[aGraySVG/256]

And what’s the point?

How many values do we need to store for our original image?

Dimensions[aGray]

So we have 686 x 948 = 650,328 values in the original image. 

To create the matrix aGraySVG, we used the svd with 100 singular values:  aGu, aGs, aGv

Dimensions[aGu]
Dimensions[aGs]
Dimensions[aGv]

This required us storing  (686 x 100) + (1 x 100) + (948 x 100) =  163, 500 values.

Notice that since we know that we only need to store the diagonal entries of aGs to recreate it.

Therefore, we are storing a lower-resolution version of the image using

N[163500/650328]

about 25% of the space of the original!

For In-Class Work #2: Another image to play around with

image2 = Import["https://tratliff.webspace.wheatoncollege.edu/2021_Fall/math221/local/office.jpg"]