How to convert 16 bit RGB to grayscale?

Hi, I’m using G’MIC 2.9.9 and I have RGB images in 16 bit depth.
I need to compare individual channels with the grayscale one so I tried to convert the images to grayscale using luminance, to_gray, “rgb2hsl split. c rm [-2,-3]” but it seems they either don’t work well or they result in 8 bit depth.

How to compute a 16 bit grayscale channel properly? a simple average of the channels?


If they’re only 3 channels, you can do the average by executing:

$ compose_channels + / 3

The above will add all of the channels together, and then divide by 3.

In addition:

There is also to_gray command.

When manipulating 16bits-valued images, it is often good to go back to a value range in [0,255] (which is the default one when considering color images).
So just divide your input by 257, then do your stuff, and eventually multiply the result by 257 again if you want to save it in 16bits:

$ gmic input16.png div 257 .... mul 257 o output16.png`

Thanks! it’s true that processing is 32 bit anyway so the scaling won’t matter.

Concerning conversion, I see that “luminance” applies gamma correction. So in my case with linear data I should use “to_gray”?

to_gray just call luminance for RGB images, so that’s not the solution. Maybe just re-apply a gamma before applying luminance, with rgb2srgb.
Otherwise, you can use directly mix_rgb with the matrix coefficients you want to compute the luminance.

For my purposes indeed rgb2srg is an option too.

I forgot to ask: why dividing by 257? shouldn’t it be 256? is it to avoid rounding errors?

Usually you want to keep your pure white value to 255, which is 65535 = 255*257.
That way, your range is indeed in [0,255].
Otherwise (dividing by 256), the image range will be [0,255.99609] which a maximum value greater than 255.

I didn’t notice your reply earlier.

After trying luminance I noticed that it’s not what I need, since the contribution of blue is very limited.
What I need is an average so your solution will be the optimal in my case.