One of the most commonly used operation in image processing is thresholding a grayscale image with a fixed value to get a binary image. For example, anything that is greater than 127 in the grayscale, can be set to 1 in the binary image and anything that is less than or equal to 127 in the grayscale image can be set to 0 in the binary image. This process is called fixed thresholding as our threshold value is set to 127.

In adaptive threshold unlike fixed threshold, the threshold value at each pixel location depends on the neighboring pixel intensities. To calculate the threshold T(x, y) i.e. the threshold value at pixel location (x, y) in the image, we perform the following steps -

1. A bxb region around the pixel location is selected. b is selected by the user.
2. The next step is to calculate the weighted average of the bxb region. OpenCV provides 2 methods to calculate this weighted average. We can either use the average (mean) of all the pixel location that lie in the bxb box or we can use a Gaussian weighted average of the pixel values that lie in the box. In the latter case, the pixel values that are near to the center of the box, will have higher weight. We will represent this value by WA(x, y).
3. The next step is to find the Threshold value T(x, y) by subtracting a constant parameter, let’s name it param1 from the weighted average value WA(x, y) calculated for each pixel in the previous step. The threshold valueT(x, y) at pixel location (x, y) is then calculated using the formula given below -

T(x, y) = WA(x, y) - param1

This is how we get our threshold value. Now, it time to program both the fixed and adaptive thresholding in OpenCV. I will be using the IPython environment for this purpose. So, let’s get started.

## Import the required modules

%pylab inline
import cv2

First of all read the image, then convert the image to grayscale and finally display the image.

im = imread("/home/bikz05/Desktop/image.jpg")
im_gray = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY)
axis("off")
title("Input Image")
imshow(im_gray, cmap = 'gray')
show()

## Fixed thresholding

We will first perform fixed thresholding on the input image. Fixed Thresholding is done using the function cv2.threshold. The signature of cv2.threshold is -

cv2.threshold(src, thresh, maxval, type[, dst]) -> retval, dst

Here,

1. src is the input image.
2. thresh is the threshold value.
3. maxval is the maximum value that can be assigned to the output.
4. type is the type of thresholding.
5. dst is the destination image

In the example, the threshold value is set to 50 and the threshold type is cv2.THRESH_BINARY i.e. any value that is greater than 50 is set to 255 and any value less than 55 is set to 0.

retval, im_at_fixed = cv2.threshold(im_gray, 50, 255, cv2.THRESH_BINARY)
axis("off")
title("Fixed Thresholding")
imshow(im_at_fixed, cmap = 'gray')
show()

## Adaptive Thresholding with mean weighted average

Adaptive Thresholding with mean weighted average is done using the function cv2.adaptiveThreshold. The signature of the function is -

cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]) -> dst

Here,

1. src  is the input image.
2. maxval is the maximum value that can be assigned to the output.
3. adaptiveMethod is set to cv2.ADAPTIVE_THRESH_MEAN_C  for mean weighted average and to cv2.ADAPTIVE_THRESH_GAUSSIAN_C for gaussian weighted average.
4. thresholdType - the type of thresholding
5. blockSize  - value of b
6. C is the constant that is subtracted from the threshold value calculated for each pixel
7. dst is the destination image

For the example, the value of b is 5 and the constant value is set to 10.

im_at_mean = cv2.adaptiveThreshold(im_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 10)
axis("off")
title("Adaptive Thresholding with mean weighted average")
imshow(im_at_mean, cmap = 'gray')
show()

## Adaptive Thresholding with gaussian weighted average

Adaptive Thresholding with gaussian weighted average is done using the function cv2.adaptiveThreshold. The signature of the function is -

cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]) -> dst

Here,

1. src is the input image.
2. maxval is the maximum value that can be assigned to the output.
3. adaptiveMethod is set to cv2.ADAPTIVE_THRESH_MEAN_C  for mean weighted average and to cv2.ADAPTIVE_THRESH_GAUSSIAN_C  for gaussian weighted average.
4. thresholdType - the type of thresholding
5. blockSize  is the value of b
6. C is the constant that is subtracted from the threshold value calculated for each pixel
7. dst  is the destination image
im_at_gauss = cv2.adaptiveThreshold(im_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 5, 7)
axis("off")
title("Adaptive Thresholding with gaussian weighted average")
imshow(im_at_gauss, cmap = 'gray')
show()

That’s it! Clearly results are better with adaptive thresholding as compared to fixed thresholding.