Image Compression Using SVD
Introduced by one of best friend, Sui Huang, I recently learned how to use svd function in Matlab to compress an image, which in my opinion is easier to be understood and implemented. Instead of the algorithm inside svd, only its usage is discussed below.
svd is a function which allows any matrix M with arbitrary size m by n, to be decomposited into 3 matrices, U (m by m), S (m by n) and V (n by n), such that
M = U * S * V'.
S is a diagonal matrix with its non-negative elements sorted in decreasing order diagonally, whereas U and V are unitary matrices. Note that those elements with larger value in S are more important to the content of an image. The idea of compressing the image is that only first number of diagonal elements in S, with corresponding columns and rows in U and V are saved. Other elements in these matrices are not saved since they are less important to the image content. Depending on different saving selections, the quality of the image varies. The actual steps of compressing and restoring an image are shown in the following Matlab statements.
First we use imread function to read a image into matrix M. Since usually the given image contains 3 layers, red, green and blue, to simplify the steps, we assume that only one layer, M, is to be compressed:
[M1, M2, M3] = imread (’filename‘,’format‘);
M = double (M1);
Here filename is the file name of the image and format is the image type of the filename, such as jpg, gif and etc.
Next, we use svd to decompose M into three matrices:
[U, S, V] = svd (M);
and we trim each of them with only first 10 valuable columns and rows saved:
U = U(:, 1:10);
V = V(:, 1:10);
S = S(1:10, 1:10);
Now we restore the image using new U, V and S matrices, and save it to a file:
M = U * S * V';
M1 = uint8 (M);
imwrite ([M1, M2, M3], ‘filename‘, ‘format‘);
Thanks Sui for providing the full source code. With variable r in the code set to 20 and 10 respectively, given an input image, two output images were generated:



As can be seen, the qualities of output images are very low, thus cannot be used in any image processing tasks that have high demands on picture quality, since this method just manipulate matrices, with no image analyzing at all. But still, it is possible to combine with other image processing techniques together, to compensate its weakness, and become useful for programs such as object recognition and video streaming.
Update:
According to the comments, we can use Lanczos method to compute “only large singular values and singular vectors (columns of U and V are actually singular vectors)“, to simply the calculation and save more memory during the process. Thanks to Sui Huang and Dr. Qiao.
November 16th, 2005 at 1:32 pm
This idea is mentioned by Dr.Qiao in CS708 scientific computing course, and we just did a simple testing on it.
It will be interesting to check if there is a way to calculate only the leading columns of U, V, and only the leading eigenvalues, without doing the whole singular value decomposition. If that method exists the complexity of compression may lower down.
November 16th, 2005 at 7:25 pm
Dr.Qiao reminded me that there are methods for computing only large singular values and singular vectors (columns of U and V are actually singular vectors). Lanczos method can do it.
February 21st, 2007 at 6:52 pm
How about the ‘bmp’ format of original image?
I try in bitmap format but the size of file after compression is same with size of file before compression. Anybody know about that? How to reduce the size of compression image in bmp format?
Regards,
Arun
February 22nd, 2007 at 9:44 am
Hi! Arun:
If a file a.bmp is compressed into b.bmp file and store in harddrive, then the file size of b.bmp will not be smaller than a.bmp. However, we can store the intermediate data which is sufficient and necessary to retrive b.bmp, and the size of intermediate is smaller.
The process of compression is:
1. read a.bmp into three matrices M1, M2 and M3
2. use svd to decompose Mi into three matrices Ui, Vi and Si, for i=1,2,3
3. ignore the minor datas in Ui, Vi and Si, such that only their sub-matrices Ui’, Vi’ and Si’ are left
4. use Ui’, Vi’ and Si’ to construct Mi’, for i=1,2,3.
5. use M1′, M2′ and M3′ to generate b.bmp and store b.bmp in harddrive, then b.bmp is a lower quality picture than a.bmp because it loses some data in step 3.
Here b.bmp have the same size as a.bmp, but if we store M1′ M2′ M3′ in some format, then we have data with much smaller size. This should be useful while we want to transmit data through network. We are not going to transmit b.bmp, instead we can transmit M1′ M2′ and M3′.
Regards
Sui
February 25th, 2007 at 11:07 pm
Dear Sui,
Thank you for your explanation. I really appreciate it.
Regards,
Arun