Dive deeper into OpenCV’s Adaptive Thresholding

Maximinusjoshus
featurepreneur
Published in
3 min readApr 14, 2021

Thresholding is the process of converting a grayscale image to a binary image (an image that contains only black and white pixels). This process is explained in the steps below:

  • A threshold value is determined according to the requirements (Say 128).
  • The pixels of the grayscale image with values greater than the threshold (>128) are replaced with pixels of maximum pixel value(255).
  • The pixels of the grayscale image with values lesser than the threshold (<128) are replaced with pixels of minimum pixel value(0).
Original Image(left) and Thresholded Image(right). Photo by Craig Whitehead on Unsplash

Adaptive Thresholding

We have seen how binary thresholding works. But this method doesn’t perform well on all images, especially when the image has different lighting conditions in different areas. In such cases, we go for adaptive thresholding. Adaptive thresholding the threshold value for each pixel is determined individually based on a small region around it. Thus we get different thresholds for different regions of the image and so this method performs well on images with varying illumination.

OpenCV provides us the adaptive threshold function to perform adaptive thresholding. The function and its parameters are given below:

dst=cv.adaptiveThreshold(src,
maxValue,
adaptiveMethod,
thresholdType,
blockSize,
C)

Parameter Explanation:
src- Source 8-bit single-channel image.
maxValue- Non-zero value assigned to the pixels for which the condition is satisfied.
adaptiveMethod- Adaptive thresholding algorithm to use
thresholdType- Thresholding type that must be either THRESH_BINARY or THRESH_BINARY_INVERSE
blockSize- Size of a pixel neighborhood that is used to calculate a threshold value for the pixel
C- Constant subtracted from the mean or weighted mean (see the details below). Normally, it is positive but maybe zero or negative as well.

The steps involved in calculating the pixel value for each of the pixels in the thresholded image are as follows:

  • The threshold value T(x,y) is calculated by taking the mean of the blockSize×blockSize neighborhood of (x,y) and subtracting it by C.
  • Then depending on the threshold type passed, either one of the following operations in the below image is performed:

Let us see a code implementation to demonstrate the same:

import cv2 as cv#read an image and convert it to grayscale
img = cv.imread('D://medium_blogs//phone_dimmed4.jpg')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
#apply normal and adaptive thresholding to the image
ret, thresh = cv.threshold(gray, 70, 255, cv.THRESH_BINARY)
adapt = cv.adaptiveThreshold(gray,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,99,3)
#create resizable windows for the images to be displayed
cv.namedWindow('adapt',cv.WINDOW_NORMAL)
cv.namedWindow('thresh', cv.WINDOW_NORMAL)
#show the image
cv.imshow('thresh', thresh)
cv.imshow('adapt', adapt)
if cv.waitKey(0):
cv.destroyAllWindows()

This is the image we are going to use to demonstrate adaptive thresholding:

Yeah, the picture was intended to be taken in poor lighting conditions with a lot of noise in the image. This image has varying lighting conditions in different regions. When we apply binary thresholding to it the output is the below image:

As you can see, the output is not so impressive, especially at the extreme ends. Let’s see what we can do with adaptive thresholding..

The readability of our image has increased enormously. This is the power of adaptive thresholding.

And that’s it. You have mastered Adaptive Thresholding! Play around with the threshold values and observe different results.

THANK YOU.

--

--