Thresholding is a simple, yet effective method for image partitioning into a foreground and background. The objective of image segmentation is to modify the representation of an image into another representation that is easier to process. For example, image segmentation is commonly used to extract objects from the background based on some properties of the object (for example, color, edges, or histogram). The simplest thresholding methods replace each pixel in the source image with a black pixel if the pixel intensity is less than some predefined constant (the threshold value), or a white pixel, if the pixel intensity is greater than the threshold value.
OpenCV provides the cv2.threshold() function to threshold images. We will see this function in further detail in the next subsections of this chapter.
In the thresholding_introduction.py script, we are applying the cv2.threshold() function with some predefined threshold values—0, 50, 100, 150, 200, and 250—in order to see how different thresholded images change.
For example, to threshold an image with the threshold value of thresh = 50, the code is as follows:
ret1, thresh1 = cv2.threshold(gray_image, 50, 255, cv2.THRESH_BINARY)
Here, thresh1 is the thresholded image, which is a black-and-white image. Pixels with an intensity of less than 50 will be black, and pixels with an intensity greater than 50 will be white.
Another example can be seen in the following code, where thresh5 corresponds to the thresholded image:
ret5, thresh5 = cv2.threshold(gray_image, 200, 255, cv2.THRESH_BINARY)
In this case, pixels with an intensity of less than 200 will be black, and pixels with an intensity greater than 200 will be white.
The output for the aforementioned script can be seen in the following screenshot:
In this screenshot, you can see the source image, which is a sample image with some equally-sized regions filled with different tones of gray. More specifically, these tones of gray are 0, 50, 100, 150, 200, and 250. The build_sample_image() function builds this sample image as follows:
def build_sample_image():
"""Builds a sample image with 50x50 regions of different tones of gray"""
# Define the different tones.
# The end of interval is not included
tones = np.arange(start=50, stop=300, step=50)
# print(tones)
# Initialize result with the first 50x50 region with 0-intensity level
result = np.zeros((50, 50, 3), dtype="uint8")
# Build the image concatenating horizontally the regions:
for tone in tones:
img = np.ones((50, 50, 3), dtype="uint8") * tone
result = np.concatenate((result, img), axis=1)
return result
The NumPy operations that have been used to build this sample image (np.ones(), np.zeros(), np.arange(), np.concatenate(), and np.fliplr()) are described briefly as follows:
- np.ones(): This returns an array of a given shape and type filled with ones; in this case, a shape of (50, 50, 3), and dtype="uint8".
- np.zeros(): This returns an array of a given shape and type filled with zeros; in this case, a shape of (50, 50, 3), and dtype="uint8".
- np.arange(): This returns evenly spaced values within a given interval, taking into account the provided step. The end of the interval (300, in this case) is not included.
- np.concatenate(): This joins a sequence of arrays along an existing axis, in this case, axis=1, to concatenate the images horizontally.
After the sample image is built, the next step is to threshold it with different threshold values. In this case, the threshold values are 0, 50, 100, 150, 200, and 250.
You will see that the threshold values are the same as the different tones of gray in the sample image. The code for thresholding the sample image with different thresholding values is as follows:
ret1, thresh1 = cv2.threshold(gray_image, 0, 255, cv2.THRESH_BINARY)
ret2, thresh2 = cv2.threshold(gray_image, 50, 255, cv2.THRESH_BINARY)
ret3, thresh3 = cv2.threshold(gray_image, 100, 255, cv2.THRESH_BINARY)
ret4, thresh4 = cv2.threshold(gray_image, 150, 255, cv2.THRESH_BINARY)
ret5, thresh5 = cv2.threshold(gray_image, 200, 255, cv2.THRESH_BINARY)
ret6, thresh6 = cv2.threshold(gray_image, 250, 255, cv2.THRESH_BINARY)
You can see how the resulting black-and-white image changes after thresholding, according to the thresholding value and the different tones of gray of the sample image.