When you look at these results, you can notice a few things:
converting to srgb before quantizing gives a visually more accurate result.
setting _is_uniform to 1 produces half the number of colors (eg. -quantize 16,1,0 produces an image with 16 colors; but -quantize 16,1,1 produces an image with 8.)
Another result I found, that wasn’t shown, is that setting _keep_values to 0 (eg -quantize 16,0,0) always produces a completely empty image.
So these are my two questions:
Why does setting _is_uniform to 1 produce half the requested number of levels?
What is the purpose of _keep_values? (since it doesn’t appear to produce a useful image)
Hello, and sorry for the delay (I’m preparing some surprises for G’MIC these days, I hope this will be out soon ).
Some random thoughts, I hope you will find answers in them:
When you read an image file in G’MIC, it is usually stored in sRGB. And yes, doing computations in linear RGB instead of RGB is often a good idea, when the algorithm involves the computation of color averaging (which is obviously the case for the -quantize command).
Indeed, setting parameter is_uniform=1 seems to do strange things when used for color images. If you use it for scalar-valued images, then it works as expected. I have to look more closely to this strange behavior. Anyway, creating a uniformly distributed colormap in the RGB cube with any number of entry N seems to be a bit a problem.
When parameter keep_values=0, then the resulting image is a scalar image (spectrum=1) where each pixel value is the indice of the color in the colormap. So, usually, those indices are quite low, and if you output this image without normalization, you won’t see anything else than a black image (except if you try to read it and display it with G’MIC for instance, where image normalization is done automatically for the visualization). It’s not really surprising you get an image that seems to be black everywhere. But if you look at the pixel values more closely, you should see that they range from 0 to nb_levels (used for the quantization).
I’ve figured out why you get fewer colors than expected when using is_uniform=1.
The algorithm quantizes the RGB space uniformly, so with a number of colors nb_levels that is always rounded to the lowest N^3 value, where N is the number of subdivisions along the R,G or B axes.
A uniformly distributed grid in the RGB color space has always a cubic number of entries.
For instance, if you provide nb_levels=16 to the -quantize command, it will tries to fit all colors of your image using a 2x2x2 uniform grid in the RGB color space (since 8^(1/3) = 2.519…).
→ so that is strictly equivalent to nb_levels=8, as 2^3 = 8.
The number of different levels that are meaningful for the command -quantize are then very limited (for RGB colors), as they can be only cubes. For 2-channels images, they can be only squares. And for scalar images, they can be whatever you want, that’s why the result looks coherent for scalar images.
So, it seems everything is logical. I would then not recommend to try quantifying a color image using a uniform distribution, unless you provide only a cubic number of levels.
Thanks a lot for the insight.
So valid numbers with keep_uniform on a multichannel image are the series N^3 where N is a positive integer:
1 (though pointless), 8, 27, 64, 125…1000…4096…8000…17576…24389…32768[etc].
I see. So if I wanted a non-uniform number of levels (for example, 4 red, 5 green, 3 blue), I should either generate my own palette, or quantize each channel individually.
re: indices: I actually wondered if that was it. However I should point out that I do not get a black image, rather I get one that appears to be transparent. Maybe I need to split the alpha channel first and recombine it afterwards?
Indeed. Quantizing each channel individually allows you to get fine control on the number of samples you use for the quantization grid along each axis in the RGB color cube.
I don’t have an explanation for this. When I use for instance -quantize 16,0 on your input .png image (which has an alpha-channel), I still get a one-channel image as expected (so without an alpha-channel), and when I save it as a .png file, I don’t get an alpha channel either.