Introducing thresholding techniques

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:

After the sample image is built, the next step is to threshold it with different threshold values. In this case, the threshold values are 050100150200, 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. 

After thresholding an image, the common output is a black-and-white image. In the previous chapters, the background of the screenshots was also white. In this chapter, for proper visualization, we have changed the background of the screenshot to a silver color using fig.patch.set_facecolor('silver').