I have a grayscale image from a photograph. I've determined that certain parts of the image are underilluminated, and that a pixel with luminance Y = 0.8 should actually be adjusted to 90% grey, i.e., that pixel should be given luminance 0.9. My question is how do I scale the other pixels nearby? I'm pretty sure multiplying all the luminances by 9/8 is wrong, because I vaguely remember hearing that in order to look uniform, the scaling has to be nonlinear. But I'm having trouble finding an equation that would enable me to make progress. (Of course I am actually writing a program to make this adjustment to a great many photographs.)
The source of my pixels is the pbmplus PGM format, about which the man page says:
Each gray value is a number proportional to the intensity of the pixel, adjusted by the CIE Rec. 709 gamma transfer function. (That transfer function specifies a gamma number of 2.2 and has a linear section for small intensities). A value of zero is therefore black. A value of Maxval represents CIE D65 white and the most intense value in the image and any other image to which the image might be compared.
If I understood this better I would probably have a better idea how to proceed.
I found a related question on making an image of uniform brightness.
Thanks Shmoopty for getting me on track. I accepted your answer then added some info to it.
You probably want gamma correction, which will keep true black and true white correct, while bending the values in between.
The formula for gamma adjustment, when input is in the range (0.0, 1.0) is:
output = pow( input, gamma )
...where gamma
will lighten when less than 1.0 and darken when above 1.0.
To push 0.8 up to 0.9, you compute log(0.9)/log(0.8)
to get a gamma of 0.4722.
Note that this is one of very many formulas -- and it is the mathematically simplest that will preserve black and white as unique colors (which some would consider important) -- however there is no single correct formula to give you what's "true".
Addendum: I verified that the gamma correction can be applied to values that are already gamma-encoded. It's hard to notate the math in markdown, but the key algebraic law is
(y**a)**b == y**(a*b) == y**(b*a) == (y**b)**a
If you apply this law, you can determine that gamma corrections commute, so it is OK, to apply the gamma correction to already corrected values. —NR
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With