Advanced Image Histograms in VB6 – Stretching and Equalizing

This is the 2nd half of a two-part project.  Part 1 is available here.

As promised, here is the second half of my histogram code project.  In this project, I’ll show you how to stretch a histogram, equalize individual channels, and – most useful of all – equalize an image’s overall luminance.

Stretching a Histogram

The most straightforward histogram function is referred to as “stretching.”  Many images contain a combination of dark and bright colors, but unless an image takes advantage of the full luminance spectrum (by including colors ranging from pure black to pure white), it may appear “dim” or “washed out.”  To improve an image like this, it is necessary to adjust the image’s colors to better span all possible luminance values.

Stretching handles this by finding the darkest and lightest values in an image, then performing an automatic conversion between that color range (max – min) and the ideal color range (pure white – pure black).

As an example, here is an image that doesn’t span the full brightness spectrum:

Normal Clouds

Notice how the top half of the histogram is empty?  The brightest pixels in this image are only a mid-level gray.

Here is the same image after running a stretch histogram algorithm:

Stretched Clouds

Notice how the histogram now stretches all the way to pure white?  Admittedly, this picture is not the best example of how stretching can be useful – but it’s a good demonstration of what stretching does.

Stretching is a fast and simple function, but its usefulness is limited.  Take the following image, for example:

Normal Tiger

The colors in this tiger picture stretch all the way from pure black to pure white, but they seem to be more heavily concentrated toward the dark end of the luminance spectrum.  To really fix this picture, we need to redistribute its colors across the spectrum in a more equal way.

Enter equalization.

Equalizing a Histogram

Equalizing is a more complex and time-consuming function than stretching, but it is capable of fixing complex lighting problems that stretching alone cannot.

Here is the tiger image post-equalization:

Equalized Tiger

See how much more balanced the histogram has become?  As another example, here is the cloud picture from above after both stretching and equalizing:

Stretched and Equalized Clouds

Equalizing has brought out details that weren’t apparent in the original image, even after stretching.

Rather than going through the gory details of how histogram equalizing works, I’m going to refer you to the excellent Wikipedia article on the subject:

http://en.wikipedia.org/wiki/Histogram_equalization

Also, I’d like to quote one very applicable comment from the above article (emphasis added by me):

The above describes histogram equalization on a greyscale image. However, it can also be used on color images by applying the same method separately to the Red, Green and Blue components of the RGB color values of the image. Still, it should be noted that applying the same method on the Red, Green, and Blue components of an RGB image may yield dramatic changes in the image’s color balance since the relative distributions of the color channels change as a result of applying the algorithm. However, if the image is first converted to another color space, Lab color space, or HSL/HSV color space in particular, then the algorithm can be applied to the luminance or value channel without resulting in changes to the hue and saturation of the image.

Because of this, I have supplied two equalizing algorithms in this project – one that equalizes any combination of color channels, and another that equalizes only luminance.  The luminance method provides the code for converting between RGB and HSL color spaces…and that code is very complex.  It’s probably worth your while to take that code on faith for now, and maybe at a future date I’ll discuss color space transformations in more detail.

 

DISCLAIMER: These download files are regularly scanned to ensure they remain free from malicious content. Unfortunately, some virus scanners will flag these .zip files as suspicious simply because they contain source code and/or executable files. I have submitted my projects to a number of companies in an attempt to rectify these false-positives. Some have been cooperative. Others have not. If your virus scanner alerts you regarding these files, please allow the file to be submitted for further analysis (if your program allows for that). This should help ensure that any false-positive warnings gradually disappear for all users.

This site - and its many free downloads - are 100% funded by donations. Please consider a small contribution to fund server costs and to help me support my family. Even $1.00 helps. Thank you!

Image Histograms in VB6 – Part 1

This is the 1st half of a two-part project.  Part 2 is available here.

I realized today that while I use image histograms in several of the projects on this site (particularly my Real-Time Image Levels demo), I don’t actually provide a stand-alone image histogram viewer.

…Until now, that is.  :)

Image histograms are HUGELY useful in image processing.  In fact, the most basic image processing algorithm – adjusting brightness – is entirely an image histogram process, theoretically speaking.  Many other functions (including contrast, invert, levels, curves, and more) can be described in terms of an image histogram as well.

So what is an image histogram, and why is it useful?

What is a histogram?

Answers.com defines histograms as:

A bar graph of a frequency distribution in which the widths of the bars are proportional to the classes into which the variable has been divided and the heights of the bars are proportional to the class frequencies.

I realize this definition is not entirely useful, but it is important to note that histograms are not used only in image processing.  Histograms are simply a type of graph – nothing more, nothing less.

A simpler way to define histograms is this: a histogram is a bar graph that shows population by category.  Categories are listed, in order, along the x-axis (or horizontally).  The population (or, alternatively, number of occurrences) of each category is listed along the y-axis (or vertically).  In this graph from the 2000 U.S. census, travel time of working Americans is shown as a histogram:

histogram_demo

Simple, eh?

So what is an Image Histogram?

As you can imagine, an image histogram is a type of histogram that tells us something about an image.  In most cases, the categories in an image histogram are brightness levels (from black to white), while the “population” of each category is the number of pixels with that brightness.

To demonstrate, let’s look at two different image histograms.

First, here is a histogram of a dark, cloudy image:

dark_histogram

Notice how the image histogram is heavily weighted to the left?  Because this image is quite dark, the histogram shows much more pixels on the left side of the graph (the dark side) than it does on the right side of the graph (the light side).

Conversely, here is the histogram of a bright image:

light_histogram

While there are some dark regions in the center of the image (indicated by the spike on the far left of our histogram), the bulk of the image is lighter, and as a result the bulk of our histogram is shifted toward the right.

Now that you know what image histograms represent, try out the attached histogram code and see if you can predict rough histogram outlines before loading an image.  (Note that as with all VB6 picture-box-based code, the program will not load images larger than ~2mb.)

 

DISCLAIMER: These download files are regularly scanned to ensure they remain free from malicious content. Unfortunately, some virus scanners will flag these .zip files as suspicious simply because they contain source code and/or executable files. I have submitted my projects to a number of companies in an attempt to rectify these false-positives. Some have been cooperative. Others have not. If your virus scanner alerts you regarding these files, please allow the file to be submitted for further analysis (if your program allows for that). This should help ensure that any false-positive warnings gradually disappear for all users.

This site - and its many free downloads - are 100% funded by donations. Please consider a small contribution to fund server costs and to help me support my family. Even $1.00 helps. Thank you!