Image Threshold with OpenCV

Image threshold is a way to make the image colors into specific colors, mostly white and black. In Threshold, we will work just like ceil and floor of a value.

This example is respective to maths where .5 is the cutoff value. For example, 12.6 can be rounded off to 13, 12.4 can be rounded off to 12. In this example, we will be using the cut off value as .5; if it is more than 0.5, then the value will be ceiled, which means the values will be moved above number if the value is less then 0.5 then the value will floored which means the value will be lowed to less value.

Cut off = .5
actual = 12.6
After threshold: actual value becomes 13
Cut off = .5
actual = 12.4
After threshold: actual value becomes 12
  • If I set the cut off to 0.3, then above both the cases will become 13.
  • If I set the cut off to 0.7, then above both the cases will become 12.

Threshold respective to OpenCV Images:

original-threshold-opencv

When handling images, we work with BGR/RGB colors, but sometimes finding the objects on the one-dimensional array (grayscale) is easier than working with three Dimensional arrays (BGR).

When we are working with one-dimensional array/grayscale, at any given pixel will have 0 to 255 values only.

When we are using threshold, we will be setting cut off value somewhere between 0 to 255. For example, if we set the cutoff as 200, then all the pixels will either 0 or 255.

  • If a pixel has a value of less than 200, then the value will be set to 0.
  • If a pixel has a value of more than 200, then the value will be set to 255.
if a value is more then cutoff then value is set to high otherwise low.

Let's do some practical :

I have taken the image of a man who is in darkens with a laptop; now, we will change RGB colors to Threshold image.

We will be using 127 as the cut off value for the threshold, the minimum value will be 0, and the maximum value will be in 255.

I have chosen 255/2 = 127 as cutoff, but you can choose any cut off value.

The threshold image will have only one color, and the color could be at high(255) value or low(0) value at pixels of the threshold pixels.

Steps to do a threshold :
  • Read the image in a specific format: We will be reading the image in GRAYSCALE, we can mention this value as the second parameter to imread() function in OpenCV
    man = cv2.imread("man.jpg", cv2.IMREAD_GRAYSCALE)

    imread_grayscale-opencv-image
    The above image is printed without any cmap value, but we can use cmap="gray" to print it in grayscale.
    Even though the above image read as Grayscale, imread() funtion prints it with Viridis color by default to make it more sense to color blind people.
    The actual image can be viewed when you set the cmap="gray."

    grayscale-threshold-image-opencv

  • threshold() function in the OpenCV will help us to create a threshold image.

    threshold_value, threshold_iamge = cv2.threshold(mono_color_image, 
                                        threshold_value, max_value, threshold_type)

threshold() funtion returns two values 1. The cutoff/threshold value, thresholdded_imae., threshold() funtion accepts 4 parameters which are

  • mono_color_image : The image to be thresholded, it should be in mono color (in our example it is black and white also known as grayscale)
  • threshold_value : the cut off value
  • max_value : value to which we need to convert the value, which is above cut off value, a lower value will be calculated automatically.
  • threshold_type : What kind of threshold we want to apply.
import cv2
import matplotlib.pyplot as plt
man= cv2.imread("man.jpg", 0)
cutoff, thres_image = cv2.threshold(man, 127, 255, cv2.THRESH_BINARY)
plt.imshow(thres_image , cmap="gray")

threshold-image-opencv

Types of thresholds in OpenCV

We have used cv2.THRESH_BINARY type for threshold in our last example, apart from this, there are other threshold types as well. We will learn most of them now.

grayscale-threshold-image-opencv

cv2.THRESH_BINARY:

If pixel intensity is greater than the set threshold/cut off, the value set to 255, else set to 0 (black).

cutoff, thres_image = cv2.threshold(man, 127, 255, cv2.THRESH_BINARY)

THRESH_BINARY-opencv

cv.THRESH_BINARY_INV:

Inverted or Opposite case of cv2.THRESH_BINARY. If pixel intensity is greater than the set threshold/cut off, the value set to 0, else set to 255 (white).

cutoff, thres_image = cv2.threshold(man, 127, 255, cv2.THRESH_BINARY_INV)

THRESH_BINARY_INV-opencv

cv.THRESH_TRUNC:

If pixel intensity value is greater than the threshold, it is truncated to the threshold. The pixel values are set to be the same as the threshold. All other values remain the same.

For example, if a pixel value is 139 and if the cut off/threshold value is 127, then the pixel value(139) will be set to 127.

If a pixel value is 98, and the cut off is 127, then there is no change in pixel value.

cutoff, thres_image = cv2.threshold(man, 127, 255, cv2.THRESH_TRUNC)

THRESH_TRUNC-opencv

cv.THRESH_TOZERO:

Pixel intensity is set to 0, for all the pixels intensity, less than the threshold value. if the pixel value id higher than the threshold/cutoff then there will be no change

cutoff, thres_image = cv2.threshold(man, 127, 255, cv2.THRESH_TOZERO)

THRESH_TOZERO-opencv

cv.THRESH_TOZERO_INV:

Inverted or Opposite case of cv2.THRESH_TOZERO.

cutoff, thres_image = cv2.threshold(man, 127, 255, cv2.THRESH_TOZERO_INV)

THRESH_TOZERO_INV-opencv

I apologize, I should have compared original, threshold images side by side.
Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions