opencv learning eleven: image binarization

Color image: three channels 0-255, 0-255, 0-255, so there can be 2^24-bit space grayscale images: one channel 0-255, so there are 256 colors of binary images: only two colors, Black and white, 1 white, 0 black
Insert picture description hereInsert picture description hereInsert picture description here
Insert picture description here

Image binarization realization

1. Global threshold

Usually, we generally don't know what threshold threshold to set to get a better binarization effect, so we can only try. For example, for a bimodal image (understood as the existence of two peaks in the image histogram), the threshold value we specify should be as close as possible to the valley between the two peaks. At this time, you can use the fourth parameter THRESH_OTSU, which automatically calculates the appropriate threshold for a bimodal image based on its histogram (for non-bimodal images, the results obtained by this method may not be ideal).

For the bimodal graph, we need to pass in one more parameter cv2.THRESH_OTSU, and set the threshold threshold to 0, and other numbers to default to 0. The algorithm will find the optimal threshold and return it as the first return value ret.

cv2.THRESH_BINARY: Binary threshold. Process the bright ones into white and the dark ones into black

cv2.THRESH_BINARY_INV: Anti-binary threshold. Treat the bright ones as black and the dark ones as white
cv2.THRESH_TRUNC: cut off threshold. Not too bright light, with an upper limit, the same dark
cv2.THRESH_TOZERO: threshold threshold into zero relatively bright portion constant, relatively dark portion is treated to black 0
cv2.THRESH_TOZERO_INV: Anti-threshold threshold value into 0, the The brighter part is processed into 0 as black, and the pixels less than or equal to the threshold remain unchanged

Insert picture description here
cv2.THRESH_BINARY: Binary threshold. Treat the bright ones as white and the dark ones as black
Insert picture description here
Insert picture description here
cv2.THRESH_BINARY_INV: inverse binary threshold. Process the bright ones into black and the dark ones into white
Insert picture description hereInsert picture description here

cv2.THRESH_TRUNC: truncation threshold. Not too bright light, with an upper limit, the same dark
Insert picture description here
Insert picture description here
cv2.THRESH_TOZERO: threshold threshold into zero relatively bright portion constant, relatively dark portion is treated to black 0
Insert picture description here
Insert picture description here
cv2.THRESH_TOZERO_INV: Anti-threshold threshold value into 0, the The brighter part is processed into 0 as black, and the pixels less than or equal to the threshold remain unchanged

Insert picture description hereInsert picture description here

import cv2 as cv
import numpy as np

def threshold_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    #ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)#cv.THRESH_OTSU计算阈值
    #ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_TRIANGLE)  # cv.THRESH_TRIANGLE计算阈值
    #不同方法阈值不同,判断二值化的方法好坏 是看信息有没有丢失
    #ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_BINARY) #手动指定阈值为127,大于127的是白色,小于127的是黑色
    ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_BINARY_INV)  #bin反 手动指定阈值为127,大于127的是黑色,小于127的是白色
    ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_TRUNC)  # 截断TRUNC, 大于的话直接变成127(截断)
    ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_TOZERO)  # 截断TRUNC, 大于的话直接变成保留,小于127的全变成0
    print("threshold value %s" % ret)
    cv.imshow("binary", binary)

src = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/lena.jpg")  #读取图片位置
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
threshold_demo(src)
#local_demo(src)
#custom_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
print("threshold value %s"% ret) #Print the
threshold value, the gray scale processing 0-255 was performed first, we use The threshold value is processed, the part of the image below the threshold value is all black, and the part of the image above the threshold value is white
Insert picture description herethreshold value: 140.0 #The acquired threshold is 140

ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_TRIANGLE)
Insert picture description herethreshold value: 67.0

ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_BINARY_INV)
inverse binary threshold. The light is processed into black, and the dark is processed into white.
Insert picture description here
Threshold value: 127.0

ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_TRUNC)
truncation threshold. The bright ones should not be too bright, there is an upper limit, and the dark ones remain unchanged.
Insert picture description here
ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_TOZERO)
threshold Threshold to 0, the brighter part remains unchanged, and the darker part is treated as black
Insert picture description herePerform a global threshold for the threshold function of OpenC to 0 . The function prototype is: threshold(src, thresh, maxval, type[, dst]) -> retval, dst The
src parameter represents the input image (multi-channel, 8-bit or 32-bit floating point).
The thresh parameter represents the threshold.
The maxval parameter represents the maximum value set when used with the THRESH_BINARY and THRESH_BINARY_INV threshold types.
The type parameter indicates the threshold type.
The retval parameter represents the return threshold. If it is a global fixed threshold algorithm, the threshold parameter value is returned. If it is a global adaptive threshold algorithm, it returns the appropriate threshold obtained by adaptive calculation.
The dst parameter means to output an image of the same size and type as src and the same number of channels

OTSU algorithm

The cv2.threshold function has two return values, the first return value is the threshold value of the image, and the second return value is the image after threshold processing,
cv.threshold(gray,0,255,cv.THRESH_BINARY | cv .THRESH_OTSU) #This is our own setting.
We may not be able to find the best threshold to divide the image, so we need the algorithm to find a threshold by ourselves, and cv.THRESH_OTSU can meet this need to find the best Good threshold. Note: It is very suitable for the case where the grayscale histogram of the image has double peaks. It will find a value between the double peaks as the threshold. For non-double peak images, it may not be very useful. Because the cv.THRESH_OTSU method generates a threshold, the second parameter (setting the threshold) of the function cv2.threshold is 0 (None), and the statement cv2.THRESH_OTSU must be added to the method parameters of cv2.threshold.
The third parameter, maxval, indicates the maximum value set when used with the THRESH_BINARY and THRESH_BINARY_INV threshold types. The maximum grayscale image we use is 255, so set it to 255.

Triangulation of image processing

ret, binary = cv.threshold(gray,0,255,cv.THRESH_BINARY | cv.THRESH_TRIANGLE)
THRESH_OTSU and THRESH_TRIANGLE are used in combination with the binarization method mentioned above. The advantage is that you don’t need to specify the threshold value yourself, the system will calculate and use it as The return value is returned. The difference is: THRESH_OTSU is most suitable for double crests THRESH_TRIANGLE is most suitable for single crests, originally used for medical division of cells, etc.

2. Local threshold adaptive threshold

cv2.adaptiveThreshold()

ADAPTIVE_THRESH_MEAN_C: Divide the image into small regions, and threshold each region. The threshold of each region is the mean value of this region minus the constant c. If the threshold is greater than the threshold, it is white, and if the threshold is smaller, it is black. The entire image has many thresholds.

ADAPTIVE_THRESH_GAUSSIAN_C: Divide the image into small areas, the threshold is the weight of the mean of each area (the mean distribution is Gaussian, the closer the center is, the higher the weight is) minus the constant c, the entire image has only one threshold
blocksize: area size , Must be an odd number.
C: When binarizing, if a pixel point minus the average value is greater than C, then this point is set to white, which can reduce the influence of noise. It is equivalent to saying that threshold = mean-C

import cv2 as cv
import numpy as np

def local_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    #binary = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 25, 10)
    binary = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 25, 10)
    #ADAPTIVE_THRESH_GAUSSIAN_C 换高斯

    cv.imshow("binary", binary)
   
src = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/lena.jpg")  #读取图片位置
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
#threshold_demo(src)
local_demo(src)
#custom_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

def local_threshold(image): gray = cv.cvtColor(image,cv.COLOR_RGB2GRAY) #To binarize the image, first perform grayscale processing dst = cv.adaptiveThreshold(gray,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY, 25,10) cv.imshow("local_threshold", dst)
Insert picture description herebinary = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 25, 10)
Insert picture description here
OpenCV's adaptiveThreshold function performs a local threshold. The function prototype is: adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]) -> dst The
src parameter represents the input image (8-bit single-channel image).
The maxValue parameter indicates the maximum value of THRESH_BINARY and THRESH_BINARY_INV. The adaptiveMethod parameter indicates the adaptive threshold algorithm, average (ADAPTIVE_THRESH_MEAN_C) or Gaussian (ADAPTIVE_THRESH_GAUSSIAN_C).
The thresholdType parameter indicates the threshold type, which must be THRESH_BINARY or THRESH_BINARY_INV.
The blockSize parameter represents the block size (odd number and greater than 1, such as 3, 5, 7...).
The C parameter is a constant and represents the number subtracted from the average or weighted average. Normally, this is a positive value, but it can also be zero or negative.

In the case of using average and Gaussian algorithms, the adaptive threshold can be obtained by calculating the weighted average of the blockSize x blockSize pixel blocks around each pixel and subtracting the constant C. If the average method is used, the weights around all pixels are the same; if the Gaussian method is used, the weights of the pixels around each pixel are obtained through the Gaussian equation according to the distance from the center point.

Insert picture description here

3. Calculate the average by yourself as a threshold, and perform binary segmentation on the image

def custom_threshold(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)#转换为灰度图
    h, w = gray.shape[:2]#高宽
    m = np.reshape(gray, [1, w*h])#将图像转换为1维数组,1行多列
    mean = m.sum() / (w*h)#求均值,把均值作为阈值
    print("mean : ", mean)
    ret, binary = cv.threshold(gray, mean, 255, cv.THRESH_BINARY)
    cv.imshow("binary", binary)

Insert picture description hereThe reshape function of numpy is to give the array a new shape without changing its data. The function prototype: reshape(a, newshape, order='C') The
a parameter represents the original array that needs to be reformed .
The newshape parameter represents a tuple of type int or int. If it is (1, 3), it means that the new array generated is 1 row and 3 columns.
The order parameter table indicates that the elements of a are read using this index order, and the elements are placed in the re-formed array using this index order. Function return value: If possible, this will be a new view object; otherwise, it will become a copy.
Note: To convert an image to a one-dimensional array, the size of the conversion dimension must be unchanged, and newshape–>[row, column] must be one line and n columns, and its size must be unchanged

Guess you like

Origin blog.csdn.net/weixin_44145452/article/details/112508204