Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is your picture decomposed into prime colors:</p> <p><img src="https://i.stack.imgur.com/QFtmX.png" alt="Lena SVD decomposed to RGB"></p> <p>Apparently you are converting colors to numbers and numbers to colors in a wrong way. You are treating the <strong>int</strong> RGB pixel as a single numeric value and pass it through the SVD numeric procedure, but the information that it's actually RGB is lost.</p> <p>Most lossy image compression methods are achieving compression by discarding low-significance bits. But when you have RGB in a single <strong>int</strong>, low-significance bits of each R, G and B are interleaved with high-significance bits. When passing the pixel as a single numeric value, this information is lost, and the SVD procedure effectively interpretes the low-significance R bits as more significant than high-significance G bits, and may attempt to discard all G and B bits completely because they are stored "after" R bits.</p> <p>For example, a light gray pixel (192,192,192) has RGB value 0xC0C0C0. Compressing this value with 1% error can yield, for example, 0xC2AE32. From the compression algorithm's point of view, this value is only 1% larger than the original which is almost not noticeable. But converting this back to RGB gives (194,174,50). The R component is indeed almost the same but G and B are corrupt. This is the source of "garbage colors" in your program. The decomposed image shows that the R component is compressed correctly, the G component becomes random noise at high compression levels, and the B component is always random.</p> <p>Another problem in your implementation is single bright pixels scattered in dark areas. These are apparently caused by numeric overflow and underflow. For example, a black pixel (0,0,0) is encoded as 0x000000 = 0; lossy compression can introduce a small error, which can be positive or negative, and can yield -1 = 0xFFFFFFFF; in RGB it becomes (255,255,255) which is white.</p> <p><strong>What to do?</strong></p> <p>If you are just testing the SVD image compression and it's enough to use grayscale images, then you should simply take the low byte from the RGB value, which is in range from 0 to 255. Correspondingly, when displaying the result or writing the output file, interpret this value as grayscale, or multiply by 0x010101 to get the full RGB value.</p> <p>If you need to compress color images, you should run the SVD algorithm separately on R, G and B components. It's the simplest way to handle color, but not the most efficient one. To get higher compression and less noticeable artifacts, it's better to convert from RGB to Lab (luminance and two chrominance channels); chrominance can be compressed more, that's the way JPEG works.</p> <p>When decompressing the image, after calculating values from SVD but before displaying them on the screen or writing to file, clamp all resulting values (R, G and B) in the range 0-255. This will eliminate scattered white dots.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload