Colour Histogram Equalisation in OpenCV (Theory & Code)

As I could not find any good examples of how to do colour Histogram Equalisation (HE) in OpenCV I thought I’d shine some light on it myself. The code I have produced is by no means the most efficient method of HE however I have written it so it is easy to understand. If you find that your HE methods are too slow then leave me a comment and I’ll write up how to make the routines more efficient.

But wait! Firstly, let’s talk a little about what exactly HE is, and more so why you might want to use it for image processing. HE in a nut shell is the ‘flattening’ of a histogram, which usually leads to a global contrast gain. This leads (often) to more vibrant colours, and allows for you to provide a way to make images look better without having to play around with contrast and brightness sliders.

OKay, so now that we’ve got a good idea of what HE is, and why it’s useful let’s talk a little about how it works, and how to equalise an image. Firstly, we need to retrieve the Red, Green and Blue values for each pixel in the image. This is so we can calculate the Luma, which is also known as the image intensity. With the RGB values we do the following:

We then process the Luma channel alone:

We then recover the colour from the colour ratios:

Note: The histogram for your image will currently look something like the following:

Then compute the cumulative distribution function:

Then use the function to assign new pixel values, leaving our resulting histogram to look something like the following:

And there we have it, histogram equalisation – but now the question is: how do we do this in code? I have written a simple image processing application, and all of the source can be viewed / downloaded from here, or you can just jump right to the histogram equalisation method. All code is in C++, and the project has been created in Qt Creator using the QtSDK for the GUI and OpenCV for Image Processing. Enjoy!

Platform Independence & Best Practices

Developing for one platform is now a thing of the past; developers as a whole should be looking more towards platform independent code. While I’ve mainly developed in virtual machine ran languages like Java this has never been a concern however as I’m starting to develop more in C/C++ I find that I am having to think a lot more about how I handle the issue of platform independent code, while ensuring my workload doesn’t increase. I have recently started to develop a small video game prototype using OpenGL/GLUT libraries, and here are some of the methods I am using to ensure that my code stays platform independent and I don’t lose any code.

Preprocessor #ifdef statements

One of the most crucial points is, I believe, ensuring that you are fully aware of the C/C++ preprocessor and its power. To ensure that I don’t need to waste my time maintaining two different forks of code, I take advantage of the preprocessor in my include statements. Here is an example:

/* If I'm developing on my Mac OSX box */
#ifdef __APPLE__
#include // your OSX includes
#endif

/* Or my Windows 7 box */
#ifdef _WIN32
#include // your Win32/64 includes
#endif

This allows me to include the GLUT/glut.h header file when compiling on OSX, and to include the GL/glut.h and windows.h file when compiling on Windows.

Whenever I create a project, I generally check it into a repository (and if I think it might be even slightly useful to somebody else, I usually put it online somewhere). Computers aren’t perfect, and dataloss is extremely expensive (in terms of time regaining / losing) – if you store your files in an online repository not only could they be useful to another developer it is just ensuring that there is another point of failure before you need to slam your head on the desk and give up; which brings me briskly onto my next point

If you’re like me, and you’ve deleted a file perminantly because you were supposed to click ‘Delete References’ but made a human mistake – Dropbox is a life saver! You will not regret it!