White Balancing — An Enhancement Technique in Image Processing

Matt Maulion
5 min readFeb 1, 2021

--

Image obtained from Fotor

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 np
import matplotlib.pyplot as plt
from 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:

Lily obtained from Drive

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))
Enhanced Lily using White Patch Algorithm

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[2] == 4:
image_grayworld[:,:,3] = 255
return image_grayworld#call the function to implement gray world algorithmskio.imshow(gray_world(lily))
Enhanced Lily using Gray World Algorithm

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'));
Patch (enclosed in blue bounding box)
Zoomed image of the patch

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[2] == 4:
image_gt[:,:,3] = 255
return image_gt

Let us see the output for both modes.

Using the max method:

skio.imshow(ground_truth(lily, img_patch, 'max'))
Enhanced Image using Ground Truth Algorithm (MAX mode)

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'))
Enhanced Image using Ground Truth Algorithm (MEAN mode)

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.

--

--

Matt Maulion
Matt Maulion

Written by Matt Maulion

A kid who uses data to make a difference.

Responses (1)