I have to compress an image using SVD. I did a few things, but all of them produced a black & white image. However, the output must be RGB. How can I compress an image without changing its original format?
The typical thing to do is the low-rank approximation on separate channels. Assume that $C$ is a channel of the RGB image $I$:
rank = 10; [U,S,V] = svd(C); L = U(:,1:rank) * S(1:rank, 1:rank) * V(:, 1:rank)';
L should be the compressed image. If you do this operation and compose the channels back, you should get a compressed RGB image.
However, such a method in my opinion is only good for mathematical understanding. It is not very practical due to the fact that it depends on image dimensions too much and cannot generate high SNR results. Or better stated, as you decrease
rank, you drastically reduce the quality of the reconstruction. For this reason, one has to retain around ~50-100 components. Better methods doing this blockwise, or formulating the compression as an energy functional exist. Image denoising is a huge area of its own.
You might want to check some results with varying
rank in this presentation.
Also, a similar question has already been asked; please follow the Stack Exchange discussion here.