Image Processing Algorithms Part 5: Contrast Adjustment
This article was originally published in issue 56 of The Crypt Mag
Last time we looked at adjusting the brightness of an image. This time we are going to look at adjusting the contrast of an image which is a little bit more complex.
The first step is to calculate a contrast correction factor which is given by the following formula where the value C is the desired level of contrast:
![]()
The next step is to perform the actual contrast adjustment itself. The following formula shows the adjustment in contrast being made to the red component of a colour:
![]()
Translating the above formulas into pseudo-code would give something like this:
factor = (259 * (contrast + 255)) / (255 * (259 - contrast)) colour = GetPixelColour(x, y) newRed = Truncate(factor * (Red(colour) - 128) + 128) newGreen = Truncate(factor * (Green(colour) - 128) + 128) newBlue = Truncate(factor * (Blue(colour) - 128) + 128) PutPixelColour(x, y) = RGB(newRed, newGreen, newBlue)
The value of contrast will be in the range of -255 to +255. Negative values will decrease the amount of contrast and conversely positive values will increase the amount of contrast.
Here we have the ‘Lena’ and ‘Mandrill’ images which have had the contrast adjusted by -128 (decreased) and +128 (increased):

‘Lena’ image with contrast adjusted by -128 (left) and +128 (right)
(click to enlarge)

‘Mandrill’ image with contrast adjusted by -128 (left) and +128 (right)
(click to enlarge)
Article copyright © 2008, 2010 Francis G. Loch

Hi, I would like to ask, where did you get the formula for contrast correction factor?any reference?
Thanks
Hi Fatima,
Because I’m using a range of -255 to 255 here to adjust the contrast I have had to use this correction factor so that it will work with the second formula for the contrast adjustment. All the correction factor does is convert the range I’m using to a range of 0 to 129.5. If you are using a different range, e.g. -100 to 100, then that would obviously require a different correction factor to work properly.
I’ve had a look back through my notes, but I couldn’t find where I originally got this from. I can’t remember if I had calculated this myself or if I’ve read it in a book or online.
Kind regards,
Francis
Hi, could you please explain, why this works (especially why the mapping to 129.5 is needed)? I see it works, but I don’t understand the logic behind it. Thank you
Thanks for your question Tiffany. Yes, I probably didn’t explain that part very well as to why the range is 0 to 129.5. This range is only for the contrast correction factor and does not represent a colour value per se. I’ll explain more about this later.
To recap the formulas are:
F = 259(C + 255) / 255(259 – C) for the contrast correction factor. C is the contrast (range = -255 to 255).
and
R’ = F(R-128) + 128 for the actual contrast adjustment. R is the red colour component (range = 0 to 255).
Let’s assume that C is zero (i.e. no change in contrast). Using the first formula we work out that F is 1. Using the second equation we see that R’ is the same as R. I’ll illustrate this with some values:
R / R’
0 = 0
64 = 64
128 = 128
196 = 196
255 = 255
Let’s now assume that C is -255. F now becomes zero. The R’ values will then become:
R / R’
0 = 128
64 = 128
128 = 128
196 = 128
255 = 128
As you can see with C turned all the way down to -255 the result is a mid-level grey no matter what the R value is.
Let’s now assume that C is 255. F becomes 129.5. The R’ values will now become:
R / R’
0 = -16448
64 = -8160
128 = 128
196 = 8934
255 = 16575
And because the R’ values are outside of the acceptable range these will be truncated so in reality the values are:
R / R’
0 = 0
64 = 0
128 = 128
196 = 255
255 = 255
Now to explain the reason why the range of the contrast correction factor is 0 to 129.5. Yes it’s true that the range should be 0 to 128, but the value of 259 used in the contrast correction factor formula has been rounded for simplicity. To get a range closer to 0 to 128 you would need to use a value of 259.047619047619 instead. However, as you can see from the R’ values you get at the higher contrast levels they end up being quite extreme and end up being truncated anyway so that fact that the range is 0 to 129.5 instead of 0 to 128 is not very significant.
I hope that explains things more clearly for you. If you still have any questions then please do not hesitate to get back in touch with me.