,.
. :%%%. .%%%.
__%%%(\ `%%%%% .%%%%%
/a ^ '% %%%% %: ,% %%"`
'__.. ,'% .-%: %-' %
~~""%:. ` % ' . `.
%% % ` %% .%: . \.
%%:. `-' ` .%% . %: :\
%(%,%..." `%, %%' %% ) )
%)%%)%%' )%%%.....- ' "/ (
%a:f%%\ % / \`% "%%% ` / \))
%(%' % /-. \ ' \ |-. '.
`' |% `() \| `()
|| / () /
() 0 | o
\ /\ o /
o ` /-|
___________ ,-/ ` _________ ,-/ _________________ INCLUDES _ OCAML _ SOURCE _ CODE _ EXAMPLES _____________________________________________

Thursday, May 15, 2014

Color Correction

As the title of this new post indicates it, we are going to see several color correction methods you can apply to an image. Basically, the color correction corresponds to a modification of the properties of the colors. In this tutorial, you will learn how to change the brightness of your image, its saturation, its contrast and I will also present the histogram equalization using the histograms of the RedGreen and Blue pixel channels and finally, we will see the logarithmic and the gamma correction.

Brightness :
n = 100
You have to know that you can increase or decrease the brightness of the pixels of your image as long as the values of the pixel components are correct. I mean that each pixel component value must be between 0 and 255.
Now if you want to increase the brightness by a coefficient n for example, all (Red,Green,Blue) pixel components must be replaced by (Red+n,Green+n,Blue+n). Note that this coefficient is generally a value between 0 and 127 or -127 and 127. Here is an example on how to implement this function :

As you may notice on my illustration, you can try to increase/decrease the brightness of a certain region of your image with different forms like a circle, a rectangle, ...

Saturation :
s = 2
Now, we will see how to change the saturation of an image. But before, what is the saturation?
In fact, this is the depth of the colors. The higher the saturation, the more vivid the colors will be.
A saturation change with a coefficient of 0 will give you a grey level of your image and a coefficient of 1 won't change anything... So let's s be the saturation coefficient of your choice and a floating point number (the best values you should try at first are the ones between 0 and 2). Here is the formula you have to use to compute all the new (Red,Green,Blue) pixel components of your image according to s :


Contrast :
n = 100
The contrast is the difference in the bright and dark areas of an image. If the contrast is high, the image looks lively; conversely, if the contrast is low, the image looks flat and monotonous. Let's n be a threshold of your choice (generally between -255 and 255), you can now compute the contrast coefficient coeff that will be used to replace all (Red,Green,Blue) pixel components by
(
 ((((Red/255) - 0.5) * coeff) + 0.5) * 255,
 ((((Green/255) - 0.5) * coeff) + 0.5) * 255,
 ((((Blue/255) - 0.5) * coeff) + 0.5) * 255
) where coeff = ((100+n) / 100)2.


Histogram equalization :
 
Before equalizing your image (= adjusting the contrast), you must know what a histogram is in image processing. You may know that a histogram is a graphical representation of the distribution of data with a horizontal x-axis and a vertical y-axis. In image processing, the values of this x-axis go from 0 to 255 and represent the different intensity levels of a RedGreen or Blue pixel component and the values of the y-axis indicate how many times a certain intensity level of a RedGreen or Blue pixel component (from the x-axis...) appears on the whole surface of your image. So the first function we must write for the equalization of any pixel channel is a function capable of generating a histogram of the Red, Green and Blue pixel channels (note that we can also generate the histogram of the grey level (= luminosity) of an image as you will see). To create a histogram, we will use a simple array of 256 indexes (representing the 256 intensity levels of the x-axis) and the content of each index will represent the distribution of these 256 intensity levels as the y-axis. All you have to do is to count the number of pixel components that have an intensity level of i and put this number at the index i of the array. It can be written like that :

As you see, I can easily get the histogram of my choice with the parameter n.
Now, we must have a function which can transform any histogram into its cumulative version.
It means that every index i of an array (representing a histogram) must contain now (the number of pixel components that have an intensity level of i) + (the number of pixel components that have an intensity level lower than i). So the last index should contain the number of pixels of your image...

We are now ready to equalize any pixel channel (note that my illustration above on the left is the result of the equalization of the 3 pixel channels). The procedure to follow is very easy. You must get the histogram of the pixel channel you want to equalize, then you have to transform this histogram into its cumulative version and finally, you just have to replace all pixel components (of the channel you want to equalize) which have an intensity level of i by
(255 * cumulative_histogram.(i)) / number of pixels of your image.
Note that if the dimensions of your image are widthxheightnumber of pixels of your image =
width * height and cumulative_histogram.(i) is the number (at the index i of an array representing a cumulative histogram) of pixel components that have an intensity level lower or equal to i.


Logarithmic correction :
The logarithmic correction is a nonlinear operation which consists in applying a logarithmic function to an image to make it brighter or darker (it depends on the function used). As we just saw that a histogram can be applied to an image, you may guess that the idea is to create a histogram which will contain the values of a certain logarithmic function and then apply this histogram to an image. Here is an example of source code where I chose to apply the logarithmic function
log(i) * (2k / log(2k)) where i is the current index of the array representing the histogram and k = 8.


Gamma correction :
γ = 0.4
The gamma correction is, like the logarithmic correction, a nonlinear operation which is generally used to make a brighter image when this image is too dark (or darker when it's too bright). This function just depends on a γ coefficient which will be used to replace all (Red,Green,Blue) pixel components of your image by (255 * (Red/255)1/γ255 * (Green/255)1/γ255 * (Blue/255)1/γ).
Note that you must use floating point numbers when you are calculating 255 * (x/255)1/γ and that the higher the γ coefficient, the more brighter the image will be. It's frequently a value between 0 and 8.

You can also observe what's happening when you apply at the same time different γ coefficients to the 3 pixel channels.