# White Balancing — An Enhancement Technique in Image Processing

As the old adage says, an image can paint a thousand words. However, what if the story it conveys does not fit the narrative you wanted to see? You are certain that it should come from that image, but unfortunately it is just not vividly apparent. What if I tell you that it is possible to uncover the context you want to get out of an image and most probably get some additional insights along the way?

That is what we are going to talk about today — image enhancement!

Image enhancement is comprised of a set of techniques that are used to refine an image. In this way, the image becomes visually easier to be perceived by humans which in turn will further facilitate improved image processing analysis. Image enhancement processing techniques include the following:

1. Fourier Transform
2. White Balancing
3. Histogram Manipulation

For this article, the discussion will be revolving around the use of various white balancing algorithms for image enhancement in python. But before anything else, let us jot down the essential libraries moving forward.

`import numpy as npimport matplotlib.pyplot as pltfrom skimage.io import imread, imshow`

# White Balancing

Firstly, what is white balancing (WB)? It is a color correcting process of removing unrealistic color casts, so that objects which appear white in person are correctly rendered white in your desired image. We will be implementing three white balancing techniques, these are:

1. White Patch Algorithm
2. Gray-world Algorithm
3. Ground-truth Algorithm

For the purpose of illustration, we will be using the image below:

# White Patch Algorithm

This approach is typical of the Color Constancy adaptation where it searches for the lightest patch to use as a white reference similar to how the human visual system does. Note that for white to be observed in the image, each channel in you RGB color space should be at its maximum value.

Code implementation in Python:

`def white_patch(image, percentile=100):    """    White balance image using White patch algorithm    Parameters    ----------    image : numpy array            Image to white balance    percentile : integer, optional                  Percentile value to consider as channel maximum    Returns    -------    image_wb : numpy array               White-balanced image    """    white_patch_image = img_as_ubyte((image*1.0 /                                    np.percentile(image,percentile,                                   axis=(0, 1))).clip(0, 1))    return white_patch_image#call the function to implement white patch algorithmskio.imshow(white_patch(lily, 85))`

As observed, it can be seen that the image became relatively brighter with the lily at the middle becoming very vibrant. This is how the white patch algorithm enhanced our image. Now, let us see the next algorithm.

# Gray-world Algorithm

The gray-world algorithm is a white balance method that assumes that your image, on average, is a neutral gray. Gray-world assumption hold if we have a good distribution of colors in the image. Considering this assumption as true, the average reflected color is assumed to be the color of the light. Therefore, we can estimate the illumination color cast by looking at the average color and comparing it to gray.

Code implementation in Python:

`def gray_world(image):    """    White balance image using Gray-world algorithm    Parameters    ----------    image : numpy array            Image to white balance        Returns    -------    image_wb : numpy array                  White-balanced image    """    image_grayworld = ((image * (access.mean() /                       image.mean(axis=(0,1)))).                      clip(0,255).astype(int))    # for images having a transparency channel        if image.shape == 4:    image_grayworld[:,:,3] = 255    return image_grayworld#call the function to implement gray world algorithmskio.imshow(gray_world(lily))`

Seeing the image, it can be observed that it did not deviate that much from the original one. One reason for this might be that the average color and its comparison to gray is not that significant. Then let us see the last algorithm.

# Ground Truth Algorithm

So far, we have made assumptions on how the color spaces behave on our images. Now, instead of making assumptions for enhancing our images, we will select a patch (portion of an image) and use that patch to recreate our desired image.

The patch chosen for this image is the one you can see below:

`from matplotlib.patches import Rectanglefig, ax = plt.subplots()ax.imshow(lily)ax.add_patch(Rectangle((650, 550), 100, 100, edgecolor='b', facecolor='none'));`

After selecting the patch, we will now proceed to enhancing our image. For this, we can do it two ways:

1. MAX method — normalize each channel of the original image to the maximum value of each channel of the region
2. MEAN method — normalize each channel of the original image to the mean value of each channel of the region

Code implementation in Python:

`def ground_truth(image, patch, mode='mean'):      """   White balance image using Ground-truth algorithm   Parameters   ----------   image : numpy array           Image to white balancr   patch : numpy array           Patch of "true" white   mode : mean or max, optional          Adjust mean or max of each channel to match patch     Returns   -------      image_wb : numpy array              White-balanced image   """   image_patch = img_patch   if mode == 'mean':       image_gt = ((image * (image_patch.mean() / \                   image.mean(axis=(0, 1))))\                   .clip(0, 255)\                   .astype(int))   if mode == 'max':       image_gt = ((image * 1.0 / image_patch.max(axis                    (0,1))).clip(0, 1))   #transparency channel   if image.shape == 4:       image_gt[:,:,3] = 255return image_gt`

Let us see the output for both modes.

Using the max method:

`skio.imshow(ground_truth(lily, img_patch, 'max'))`

Aside from vividly emphasizing the lily, it can be observed that the lily pads surrounding the flower were enhanced as well. The green color channel was highlighted greatly. Let us see how is this different from using the mean as the mode.

Using the mean method:

`skio.imshow(ground_truth(lily, img_patch, 'mean'))`

The output is slightly closer to the white patch output but the latter is brighter. It also emphasized the color of the lily but instead of highlighting the color of the pads, it only brightened it.

For the ground truth algorithm, the output image depends greatly on the choice of the patch image. So, choose the patch wisely by visualizing what kind of enhanced image you would want to arrive at.

And there you have it! Wonderful, you are now able to enhance images using 3 different methods. Keep posted for my next updates! See you next time.

A kid who uses data to make a difference.

## More from Matt Maulion

A kid who uses data to make a difference.