Image segmentation is an essential operation for extracting objects and features from an image. In general object- extraction is an important step in different advanced image processing operations. Among many different ways of segmentation, thresholding is one of the segmentation which produces a binary image. The binary image is an image with pixel values either 0 or 255. The process of converting pixel value to zero or 255 is called thresholding.
In image threshold operation each pixel value is compared with a threshold and if the pixel value is above the threshold it will be assigned to 255 otherwise it will be made as zero, with this process after completion of the thresholding the resulting image is a binary image which contains black and white pixels.
0 | 255 | 255 |
0 | 255 | 0 |
255 | 0 | 255 |
46 | 193 | 210 |
91 | 145 | 86 |
189 | 105 | 175 |
When the threshold value is 125. The resulting binary image looks like as shown in the right.
import numpy as np
import cv2
img_data = cv2.imread ("C:/Users/c2plabs/Desktop/blocks_for_thresh.png",0)
cv2.imshow ("Black",img_data)
cv2.imwrite ("C:/Users/c2plabs/Desktop/bw_img.png",img_data)
height,width = img_data.shape
thresh_val = 125
print (height)
print (width)
#Creating Numpy array with dimensions same as the of Image
thresh_img = np.zeros([height,width],'uint8')
for row in range (0,height):
for column in range (0,width):
if img_data[row][column] > thresh_val:
thresh_img[row][column] = 255
cv2.imshow ("thresh_img",thresh_img)
cv2.imwrite ("C:/Users/c2plabs/Desktop/thresh_img.png",thresh_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
The code snippet listed above performs simple thresholding operation on the input image, lines 1,2 import numpy and OpenCV libraries, line 4 reads the input image data in a grayscale format, then read image is displayed at line 6 and save back the grayscale image to disk at line 8.
At line 11 height and width of the image is obtained using shape (img_data.shape). These height and width variables are used to create a new multidimensional array at line 18. This new array ( thresh_img) is used to create a threshold image. For this example, we have taken a threshold value of 125 at line 13 (thresh_val = 125).
From line 20 to line 23 we iterate image data using nested for loops and compare the value of each pixel. If the pixel value is greater than the threshold value the make it as 255 (white pixel) otherwise it’s value remain zero (black pixel) as we are filling multidimensional array created using np.zeros command.
OpenCV supports functions to perform thresholding directly instead of accessing pixels directly. cv2.threshold() function is used for performing threshold operation on image data.
cv2.threshold(img_data,thresh_val, max_pixel_value, threshold_type)
img_data: pixel data of the grayscale image
thresh_val: Threshold value
max_pixel_value : Maximum value of the pixel, for the grayscale image it is 255
threshold_type: OpenCV supports different types of thresholding, generally used one is cv2.THRESH_BINARY, and other types of thresholding are cv2. THRESH_BINARY _INV, cv2.THRESH_TOZERO etc…
Code for Simple thresholding using OpenCV function:
import numpy as np
import cv2
img_data = cv2.imread ("C:/Users/admin/Desktop/blocks_for_thresh.png",0)
cv2.imshow ("Black",img_data)
thresh_val = 125
height,width = img_data.shape
ret_val, thresh_img = cv2.threshold (img_data,thresh_val,255,cv2.THRESH_BINARY)
cv2.imshow ("Thresh",thresh_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
In simple thresholding, we use a constant value as threshold value. But sometimes this method some of the objects will be turned completely black or white based on the value. In such cases, adaptive thresholding will give better results. Code for adaptive threshold is given below for reference.
import numpy as np
import cv2
img_data = cv2.imread ("C:/Users/admin/Desktop/blocks_for_thresh.png",0)
cv2.imshow ("Black",img_data)
thresh_val = 125
height,width = img_data.shape
thresh_img = cv2.adaptiveThreshold (img_data,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,85,2)
cv2.imshow ("Thresh",thresh_img)
cv2.waitKey(0)
cv2.destroyAllWindows()