I am trying to learn SVD for image processing... like compression.
My approach: get image as BufferedImage using ImageIO... get RGB values and use them to get the equivalent grayscale value (which lies within 0-255) and store it in a double[][] array. And use that array in SVD to compress it.
I am getting my USV matrices correctly... hope so. I get from U from AATranspose (AAT), and V from ATA.
Let me give an example
A is my original matrix.
A = 7.0 3.0 2.0
9.0 7.0 5.0
9.0 8.0 7.0
5.0 3.0 6.0
U = -0.34598 -0.65267 -0.59969 -0.30771
-0.57482 -0.27634 0.26045 0.72484
-0.64327 0.21214 0.44200 -0.58808
-0.36889 0.67280 -0.61415 0.18463
S = 21.57942 0.00000 0.00000
0.00000 3.35324 0.00000
0.00000 0.00000 2.02097
0.00000 0.00000 0.00000
VT = -0.70573 -0.52432 -0.47649
-0.53158 -0.05275 0.84536
-0.46838 0.84989 -0.24149
So now I have to do outer product expansion, leaving out a few terms for compression. Lets call the truncated terms k.
When I let k = 1, and do outer product expansion with the singular values, this is what I get as my new matrix
B = 6.43235 4.03003 1.70732
9.24653 6.55266 5.12711
9.41838 7.24083 7.21571
4.41866 4.05485 5.70027
As you can see, some values in B (which I think should be my final matrix after SVD) are greater than my original matrix.
A
is just a test matrix. I would later try to compress a grayscale image, and there the values have to be 0-255. Anything > 255 wouldn't help me.
Where am I going wrong?
You raise an interesting point. The ultimate solution is to use thresholding to clear up this malady; the SVD is working as designed.
An example follows. Start with $\mathbf{A}$, a picture (here Camille Jordan), and perform a low rank approximation up through the first 4 singular values. (A final plot shows the quality with the first 30 singular values.)
The input picture was adjusted so that the values are bound within the interval $[0,1]$. The table below shows how the extrema drift with each approximation. The graphics tools clipped the values to maintain the interval $[0,1]$.