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

Tuesday, July 1, 2014

More about Histograms

Before reading this new post, I want you to read this one. It talks about different color correction methods and more precisely about the histogram equalization (you can read only this specific part). Indeed, you must know what is a histogram in image processing and how to create one in order to do certain manipulations on an image. You must also have an idea about what I'm talking about if I say "cumulative histogram" or "equalized histogram". We will also see a new one which is very particular and called horizontal or vertical "Black&White projection".

Now, we know the histograms are really useful in image processing. We already saw 2 ways to use them with the histogram equalization and the logarithmic correction of an image. And it's time to do some tests which will consist in trying to display several types of histograms based on the analysis of our famous test image of Lena :
To display any type of histogram, you firstly have to create one. Then you must find the number which represents the most frequent intensity level in the array representing the histogram. This number will be useful to determine the height of the vertical lines of your histogram corresponding to the distribution of each intensity level. Let's imagine that the number of pixels of the most frequent intensity level is represented by a vertical line with a height equal to h, you can then determine the height of the line representing any other intensity level with a simple cross-multiplication :
(h * nb of pixels of any intensity level) / nb of pixels of the most frequent intensity level.
The following display_histogram function creates an image corresponding to a certain histogram.

I created an image with dimensions 256x256 not by chance but because RGB colors have exactly 256 intensity levels which go from 0 to 255 and are represented here by the image width. In addition to that, each intensity level of any pixel channel is easily distinguishable because of the color gradient that I applied. Note that the new_img function which creates an empty image with specified dimensions and the save function which saves an image with a specified filename were already presented here.

Here are all the different types of histograms the previous function can provide (note that I got the cumulative histograms by replacing get_histogram by get_histogram_cumulative in the previous source code example, these 2 last functions were presented here. And for the equalized histograms, you just have to previously equalized your image with the equalization function before getting a histogram of any pixel channel. This function was also presented here) :
Grey level
  

Red channel
  

Green channel
  

Blue channel
  
I think it's not necessary to precise that the classic histograms are on the left, the cumulative histograms are at the middle, the equalized histograms are on the right (but I just did it...) so now, if you are a good observer, you may notice that the display_histogram function isn't complete. Indeed, you can see on all these histograms that I also tried to display a distinct vertical line. This line just indicates the position of the intensity level that is the most frequent on the image of Lena. A last step could be to verify that these histograms are correct... You can compare them to what the GIMP image editing software offers with the same image of Lena for example (details).

Black&White projection :
As I said it, the Black&White projection is a particular histogram. In fact, it represents an analysis (which can be horizontal or vertical) of a black and white image. My 2 projections above show 2 different horizontal analysis of 2 different black and white images of Lena (the 1st black and white image of Lena was obtained using the "Averaging" grey level method for the passage in black and white and the 2nd one was obtained using the Blue channel as grey level method). Each row (or each column if it was a vertical projection) of these 2 projections gives us an idea about the exact quantity of black pixels compared to the white pixels on the same row of the corresponding original black and white image. So if you want to display a Black&White projection, you have to convert your image in black and white. The easiest way consists in converting your image in grey level with the method of your choice (here are the different methods we saw) and then replace the current pixel by the black color if the intensity level of this pixel is under 128 otherwise by the white color (note that I will certainly present more in details the black and white filter using dithering methods in a future post). Now, if you want to apply a horizontal projection, you must use an array of exactly h indexes where h is the image height (w indexes where w is the image width for a vertical projection). Each index i must contain the number of black pixels on the row i of your black and white image (on the column i for a vertical projection). Finally, create a totally black surface with the same dimensions than the original image ones and on each row i (each column i for a vertical projection), replace the pixels after the nth one by the white color where n is the number of black pixels indicated at the index i of the array.

Note that bw is the function which converts an image in black and white, the parameter style is just a string variable corresponding to the grey level method to use and the matrix_to_img function which converts a matrix into an image was already presented here...


The next post will be so much c o l o r f u l !