OpenCV study notes 04--image threshold processing, threshold function, adaptiveThreshold function, Otsu method processing

content

(1), threshold() function

(2), adaptiveThreshold()--adaptive threshold processing

 (3) Otsu processing


Introduction: The usefulness of thresholding in images can be summed up in one sentence: we set a threshold x, when the pixel value in the image is greater than x, what do we want to do with these pixel values; when it is less than x, what do we want to do? Process these pixel values. The threshold() function in thresholding gives a good solution. By thresholding we can get a binary image. Let's learn it. The images we use here are all 8-bit grayscale images.

(1), threshold() function

Thresholding can be done in opencv using the cv2.threshold() function.

reval, newimg = cv2.threshold (img, x, maxval, type)

Parameter explanation:

reval : is a return value, this value is the value of x we ​​set in the threshold parameter.

newimg : is our thresholded image.

img: is the image we want to threshold, the object we operate on.
x: is a threshold we set, that is, when we operate on the value of the pixel in the image img, we use this threshold x as the standard for threshold processing.

maxval: When we compare the value of the pixel in the image img with the threshold x, if the value of the pixel in img is greater than or less than the value of x, we set the value of the pixel in the image to maxval, maxval The maximum value is 255. Others are set to 0. This parameter only works when type is THRESH_BINARY or THRESH_BINARY_INV.

type: We will analyze this parameter carefully, because this parameter has a leading role in the result in threshold processing.

The main types of types are as follows:

THRESH_BINARY: Also known as binarization thresholding, when type is this type, it means that when we compare the pixel value in the image img with the threshold x, when the pixel value in the image img is greater than the threshold x, the current image of the image is compared. The value of the pixel is set to maxval, or 0 if it is not greater than. That is, the image after thresholding is a binary image consisting of the maximum value maxval and 0.

THRESH_BINARY_INV: Also known as inverse binarization thresholding, when type is this type, it means that when we compare the pixel value in the image img with the threshold x, when the pixel value in the image img is greater than the threshold x, the image's The value of the current pixel is set to 0, and if it is not greater than that, it is set to maxval.

THRESH_TRUNC: Also called truncation threshold processing. When type is this type, it means that when we compare the pixel value in the image img with the threshold x, when the pixel value in the image img is greater than the threshold x, then set the value of the pixels greater than x to x, if the value is not greater than x, we do not process it.

THRESH_TOZERO_INV: Also called over-threshold 0 processing. From the literal meaning, we can understand that when the type is this type, it means that when we compare the pixel value in the image img with the threshold x, when the pixel value in the image img is greater than the threshold x, then the value greater than x The value of the pixel is set to 0, and the value not greater than x is not processed.

THRESH_TOZERO: Also called threshold 0 processing. It's the exact opposite of the above. When type is this type, it means that when we compare the pixel value in the image img with the threshold x, when the pixel value in the image img is not greater than the threshold x, then set the value of the pixel greater than x is 0, and we do not process the value greater than x.

Text is hard to look at, and visualization allows us to clearly understand the difference between them. Next, let's practice this function through practice. When the type takes different types, the difference can be understood at a glance through the program. Let's take an example with a simple array, and then use an image to see the difference.

Practice using functions with arrays. The sample code is as follows:

import numpy as np
import cv2
# 声明一个数组,用生成随机数的函数np.random.randint生成一个数组。
data = np.random.randint(0, 256, size=[4, 4], dtype=np.uint8)
print('data=\n', data)
# 使用cv2.threshold()函数
# 设定阈值x为127,这个阈值是自己定义的哈, maxval=255,type = cv2.THRESH_BINARY
reval1, data_THRESH_BINARY = cv2.threshold(data, 127, 255, type=cv2.THRESH_BINARY)
print('data_THRESH_BINARY=\n', data_THRESH_BINARY)

# 设定阈值x为120, maxval=255,type = cv2.THRESH_BINARY_INV
reval2, data_THRESH_BINARY_INV = cv2.threshold(data, 120, 255, type=cv2.THRESH_BINARY_INV)
print('data_THRESH_BINARY_INV=\n', data_THRESH_BINARY_INV)

# 设定阈值x为200,maxval=255,type = cv2.THRESH_TRUNC
reval3, data_THRESH_TRUNC = cv2.threshold(data, 200, 255, type=cv2.THRESH_TRUNC)
print('data_THRESH_TRUNC=\n', data_THRESH_TRUNC)

# 设定阈值x为200,maxval=255,type = cv2.THRESH_TOZERO_INV
reval4, data_THRESH_TOZERO_INV = cv2.threshold(data, 200, 255, type=cv2.THRESH_TOZERO_INV)
print('data_THRESH_TOZERO_INV=\n', data_THRESH_TOZERO_INV)

# 设定阈值x为100,maxval=255,type = cv2.THRESH_TOZERO
reval5, data_THRESH_TOZERO = cv2.threshold(data, 100, 255, type=cv2.THRESH_TOZERO)
print('data_THRESH_TOZERO=\n', data_THRESH_TOZERO)



result:

Randomly generated array:

The results of binarization thresholding and de-binarization thresholding are as follows:

 The truncation threshold processing results are as follows, and those greater than 200 are changed to 200:

 The results of over-threshold zero processing and low-threshold zero processing are as follows:

 It can be combined with the types we explained above and the processing methods are also different, and then understand the above results, it will be clear.

Use an image to illustrate the use of the function. Here we make a slight adjustment to the above code, replace the array with an array of images, and then perform threshold processing, and the effect can be seen by directly observing the image. code show as below:

import numpy as np
import cv2
# 读取图像位置
filename = r'C:\Users\LBS\Desktop\lena01.png'
# 读取图像,0的意思是读取灰度图像。
data = cv2.imread(filename, 0)
# 打印图像的矩阵
print('图像矩阵data=\n', data)
# 显示原图像
cv2.imshow('01', data)
# 使用cv2.threshold()函数
# 设定阈值x为127,这个阈值是自己定义的哈, maxval=255,type = cv2.THRESH_BINARY
reval1, data_THRESH_BINARY = cv2.threshold(data, 127, 255, type=cv2.THRESH_BINARY)
print('data_THRESH_BINARY=\n', data_THRESH_BINARY)
cv2.imshow('02', data_THRESH_BINARY)
# 设定阈值x为120, maxval=255,type = cv2.THRESH_BINARY_INV
reval2, data_THRESH_BINARY_INV = cv2.threshold(data, 120, 255, type=cv2.THRESH_BINARY_INV)
print('data_THRESH_BINARY_INV=\n', data_THRESH_BINARY_INV)
cv2.imshow('03', data_THRESH_BINARY_INV)
# 设定阈值x为200,maxval=255,type = cv2.THRESH_TRUNC
reval3, data_THRESH_TRUNC = cv2.threshold(data, 200, 255, type=cv2.THRESH_TRUNC)
print('data_THRESH_TRUNC=\n', data_THRESH_TRUNC)
cv2.imshow('04', data_THRESH_TRUNC)
# 设定阈值x为200,maxval=255,type = cv2.THRESH_TOZERO_INV
reval4, data_THRESH_TOZERO_INV = cv2.threshold(data, 200, 255, type=cv2.THRESH_TOZERO_INV)
print('data_THRESH_TOZERO_INV=\n', data_THRESH_TOZERO_INV)
cv2.imshow('05', data_THRESH_TOZERO_INV)
# 设定阈值x为100,maxval=255,type = cv2.THRESH_TOZERO
reval5, data_THRESH_TOZERO = cv2.threshold(data, 100, 255, type=cv2.THRESH_TOZERO)
print('data_THRESH_TOZERO=\n', data_THRESH_TOZERO)
cv2.imshow('06', data_THRESH_TOZERO)
cv2.waitKey()
cv2.destroyAllWindows()

result:

The image and array corresponding to the original image are shown in the following figure.

 

 The corresponding image and array after binarization thresholding are shown in the figure below.

 The corresponding image and array after de-binarization thresholding are shown in the figure below.

 The corresponding image and array after truncation thresholding are shown in the following figure.

 

The corresponding images and arrays after over-threshold zero processing are shown in the figure below.

  The corresponding image and array after low-threshold zero processing are shown in the figure below.

 The above is the use of the function threshold(). You can practice by changing the size of the threshold x to observe the effect of the resulting image.

(2), adaptiveThreshold()--adaptive threshold processing

 When we perform threshold processing, if the color of our image is not balanced, we cannot perform effective segmentation through a threshold x, then we can use adaptive threshold processing, which is like a mask, about the mask If you don't understand the concept, you can take a look at my image processing notes 03. This threshold processing is based on the weighted average of the pixel values ​​in the surrounding neighborhood of the current pixel to obtain a threshold, and the operation after obtaining the threshold is the same as the previous one. .

The syntax of this function is as follows:

reval, newimg = cv2.threshold (img,  maxval, adaptiveMethod, type,blocksize,C)

Parameter description: The same parameters as the threshold function will not be described here. You can see the beginning of the article. Let's talk about the meaning of the new parameters added here.

adaptivemeth _ The weights are assigned through the Gaussian function, but the weights are different, and the pixel operations of the image are weighted and averaged. Then subtract the constant C to get the threshold x of the pixel of the current image, and calculate this threshold for the pixels of the image one by one. The thresholding operation of an image is completed.

type: can only be THRESH_BINARY_INV or THRESH_BINARY

blocksize: Specifies the size of the mask, usually odd 3, 5, 7...

C: is a constant

We use this function to process the image, and make a comparison with the thresh function.

code show as below:

import numpy as np
import cv2
# 读取图像位置
filename = r'C:\Users\LBS\Desktop\lena01.png'
# 读取图像,0的意思是读取灰度图像。
data = cv2.imread(filename, 0)
# 打印图像的矩阵
print('图像矩阵data=\n', data)
# 显示原图像
cv2.imshow('01', data)
# 使用cv2.threshold()函数
# 设定阈值x为127,这个阈值是自己定义的哈, maxval=255,type = cv2.THRESH_BINARY
reval1, data_THRESH_BINARY = cv2.threshold(data, 127, 255, type=cv2.THRESH_BINARY)
print('data_THRESH_BINARY=\n', data_THRESH_BINARY)
cv2.imshow('02', data_THRESH_BINARY)
# 使用cv2.adaptiveThreshold()函数,adaptiveMethod=cv2.ADAPTIVE_THRESH_MEAN_C
data_Mean = cv2.adaptiveThreshold(data, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, blockSize=5, C=3)
print('data_Mean=\n', data_Mean)
cv2.imshow('03', data_Mean)
# 使用cv2.adaptiveThreshold()函数,adaptiveMethod=cv2.ADAPTIVE_THRESH_GAUSSIAN_C
data_GAUSS = cv2.adaptiveThreshold(data, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, blockSize=5, C=3)
print('data_Mean=\n', data_GAUSS)
cv2.imshow('04', data_GAUSS)
cv2.waitKey()
cv2.destroyAllWindows()

result:

The original image is:

The results of the threshold function processing, the MEAN method and the GAUSSIAN method processed by the adaptiveThreshold function are as follows:

 (3) Otsu processing

       This processing is to overcome the situation where our manually set threshold x is unreasonable for the current image. For example, the pixel value of the current image is greater than 125, and then we set a threshold value of 125, using binarization, the pixel value of the image will become 255, and the image is a whiteboard, so thresholding is not desirable, then We can process it through Otsu, which can set an optimal threshold based on all pixel values ​​in the current image, which will comprehensively consider all possible thresholds.

       In opencv, we only need to add one more parameter cv2.THRESH_OTSU to the parameter type in the function threshold().

It is declared as follows:

reval, newimg = cv2.threshold (img, x, maxval, type+THRESH_OTSU)

It should be noted that when using the Otsu method, the threshold needs to be set to 0, and the function threshold will automatically find the optimal threshold.

Im : reval , newimg = cv2.threshold (img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

 See it in practice. code show as below:

import numpy as np
import cv2
# 读取图像位置
filename = r'C:\Users\LBS\Desktop\02.png'
# 读取图像,0的意思是读取灰度图像。
data = cv2.imread(filename, 0)
# 打印图像的矩阵
print('图像矩阵data=\n', data)
# 显示原图像
cv2.imshow('01', data)
# 使用cv2.threshold()函数加上Otsu方法
# 设定阈值x为0,这个阈值需为0, maxval=255,type = cv2.THRESH_BINARY+cv2.THRESH_OTSU
reval1, otsu = cv2.threshold(data, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
print('otsu=\n', otsu)
cv2.imshow('02', otsu)
cv2.waitKey()
cv2.destroyAllWindows()

 The result is as follows:

The original image, the image after processing, here we do not specify the threshold.

 You can find an image material with a relatively high overall brightness, and then compare the images obtained with the Otsu method and without the Otsu method, and you will know the advantages of this method.

It is not easy to create, please indicate the source when reprinting.

 

 

Guess you like

Origin blog.csdn.net/BaoITcore/article/details/124066618