The problem is that I can't understand how the "official" JPG->PGM convertitors work in terms of what value to assign to the final pixel (i guess, 0->255) starting from the classic RGB format.
There is likely a gamma adjustment in the conversion those "official" tools are using.
That is, it is not just a linear transform.
See this Wikipedia section for the details: Converting color to grayscale
I believe you want to use the formula for Csrgb.
Try it out and see if it matches the results you're expecting.
Basically, you'll do this:
- Take
R, G, Bcolor (each in[0,1]range)- If they're in the range
0..255instead, simply divide by255.0
- If they're in the range
- Compute
Clinear = 0.2126 R + 0.7152 G + 0.0722 B- This is likely the linear transform you were applying before
- Compute
Csrgbaccording to it's formula, based onClinear- This is the nonlinear gamma correction piece you were missing
- Check out this WolframAlpha plot
Csrgb = 12.92 ClinearwhenClinear <= 0.0031308Csrgb = 1.055 Clinear1/2.4 - 0.055whenClinear > 0.0031308
The problem is that I can't understand how the "official" JPG->PGM convertitors work in terms of what value to assign to the final pixel (i guess, 0->255) starting from the classic RGB format.
There is likely a gamma adjustment in the conversion those "official" tools are using.
That is, it is not just a linear transform.
See this Wikipedia section for the details: Converting color to grayscale
I believe you want to use the formula for Csrgb.
Try it out and see if it matches the results you're expecting.
Basically, you'll do this:
- Take
R, G, Bcolor (each in[0,1]range)- If they're in the range
0..255instead, simply divide by255.0
- If they're in the range
- Compute
Clinear = 0.2126 R + 0.7152 G + 0.0722 B- This is likely the linear transform you were applying before
- Compute
Csrgbaccording to it's formula, based onClinear- This is the nonlinear gamma correction piece you were missing
- Check out this WolframAlpha plot
Csrgb = 12.92 ClinearwhenClinear <= 0.0031308Csrgb = 1.055 Clinear1/2.4 - 0.055whenClinear > 0.0031308
To harold's point about the "Y plane": standard color JPEGs are encoded using the YCbCr colorspace, where Y is the luminance component (i.e. the brightness) and Cb and Cr are the blue-difference and red-difference chroma components. So one way of turning a color JPEG into a grayscale one is to simply drop the Cb and Cr components.
There is a utility called jpegtran than can do this losslessly, using the -grayscale option. (The lossless part would really only matter if you wanted to end up with a JPEG and not PGM, to avoid generation loss.) In any case, this would probably be the fastest way to do this transformation, because it doesn't even decode the image into pixels, much less do math on each one.
colors - Convert grayscale value to RGB representation? - Stack Overflow
Help Needed with RGB to Grayscale Conversion in TouchDesigner Using Reorder and Math TOPs
Confusion about Image distortion converting from RGB to 16-bit?
Can't change image color space to grayscale
Videos
The problem is that I can't understand how the "official" JPG->PGM convertitors work in terms of what value to assign to the final pixel (i guess, 0->255) starting from the classic RGB format.
There is likely a gamma adjustment in the conversion those "official" tools are using.
That is, it is not just a linear transform.
See this Wikipedia section for the details: Converting color to grayscale
I believe you want to use the formula for Csrgb.
Try it out and see if it matches the results you're expecting.
Basically, you'll do this:
- Take
R, G, Bcolor (each in[0,1]range)- If they're in the range
0..255instead, simply divide by255.0
- If they're in the range
- Compute
Clinear = 0.2126 R + 0.7152 G + 0.0722 B- This is likely the linear transform you were applying before
- Compute
Csrgbaccording to it's formula, based onClinear- This is the nonlinear gamma correction piece you were missing
- Check out this WolframAlpha plot
Csrgb = 12.92 ClinearwhenClinear <= 0.0031308Csrgb = 1.055 Clinear1/2.4 - 0.055whenClinear > 0.0031308
The quick and dirty approach is to repeat the grayscale intensity for each component of RGB. So, if you have grayscale 120, it translates to RGB (120, 120, 120).
This is quick and dirty because the effective luminance you get depends on the actual luminance of the R, G and B subpixels of the device that you're using.
If you have the greyscale value in the range 0..255 and want to produce a new value in the form 0x00RRGGBB, then a quick way to do this is:
int rgb = grey * 0x00010101;
or equivalent in your chosen language.