Image Preprocessing (1)

Table of contents

Binarization

Fixed Threshold Binarization

Adaptive Threshold Binarization

Otsu's binarization

Erosion, Dilation, Opening, Closing

Binarization

Binarization is to convert an image into an image containing only two grayscale values, usually by limiting the pixel values ​​in the image to two fixed values, such as 0 and 255, which are used to represent black and white.

In the binarization process, the pixels are divided into two categories according to the comparison between the gray value of the pixel and the set threshold: the pixels below the threshold are set to black, and the pixels above the threshold are set to white. On the one hand, it is used to reduce the dimension of the data, and on the other hand, it can highlight the contour structure by eliminating the interference caused by the noise in the original image. This transformation can highlight object outlines in an image, simplify the image, and extract objects of interest.

Fixed Threshold Binarization

According to the grayscale characteristics of the whole image, a fixed threshold is selected to divide the image into two parts. All pixels below the threshold are set to black, and pixels above the threshold are set to white; the following is the fixed binarization code:

import cv2  
import numpy as np  
import matplotlib.pyplot as plt
#读取图像
img = cv2.imread('22.jpg')
# 应用全局阈值二值化
_, binary_image = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# 显示二值化后的图像
cv2.imshow('Binary Image',binary_image )
# 显示原图
cv2.imshow(' Image',img )
cv2.waitKey(0)
cv2.destroyAllWindows()

 The picture above is the result picture after code execution

Adaptive Threshold Binarization

Adaptive Thresholding (Adaptive Thresholding) is a method of converting an image into a black and white (binarized) image, where the threshold is determined based on the brightness of a local area of ​​the image, rather than applying a fixed threshold globally.

This method can help to solve binarization problems in the presence of non-uniform lighting conditions in the image. In adaptive threshold binarization, an image is segmented into many small local regions, and then an applicable threshold is calculated for each local region, so that the thresholds of different regions can adapt to their local characteristics.

Following are the basic steps of adaptive threshold binarization:

  1. Convert the image to grayscale (if the original image was not grayscale).

  2. Specify an appropriate local area size (usually an odd number), such as 3x3, 5x5, etc.

  3. For each pixel in the image, calculate the average gray value or Gaussian weighted average gray value of the local area around the pixel.

  4. Binarization is achieved by comparing the gray value of that pixel with a calculated local threshold, setting the pixel value to 0 (black) or 255 (white).

Adaptive threshold binarization can be implemented by a variety of algorithms, two of which are commonly used:

  • Mean Thresholding algorithm (Mean Thresholding): Use the average gray value of the local area as the threshold.
  • Gaussian Weighted Mean Thresholding algorithm (Gaussian Weighted Mean Thresholding): Use the Gaussian weighted average gray value of the local area as the threshold, so that pixels with greater weight contribute more to the threshold.

These algorithms can be selected according to the needs of specific applications. Adaptive threshold binarization helps to extract features or contours of target objects in images with uneven lighting conditions. The code example is as follows:

import cv2

# 读取图像并转换为灰度图像
image = cv2.imread('22.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 自适应阈值二值化
threshold = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)

# 显示结果
cv2.imshow('Thresholded Image', threshold)
# 显示原图
cv2.imshow(' Image',img )
cv2.waitKey(0)
cv2.destroyAllWindows()

 The above is the result after the code is executed

Otsu's binarization

Otsu's binarization is a method to automatically determine the global threshold value of an image, which converts the image to black and white (binarized) image. This approach achieves adaptive binarization of images by minimizing the between-class variance to determine the optimal threshold.

Following are the basic steps of Otsu's binarization:

  1. Convert the image to grayscale (if the original image was not grayscale).

  2. Calculate the histogram of the image and count the number of pixels at each gray level.

  3. Iterate over all possible thresholds (0 to 255), computing the between-class variance when segmenting an image using the current threshold.

  4. According to the value of the between-class variance, the optimal threshold is selected so that the variance between the two classes after segmentation is minimized.

  5. Set the pixels greater than or equal to the optimal threshold in the image to 255 (white), and the pixels smaller than the optimal threshold to 0 (black) to achieve binarization.

Using Otsu's binarization can effectively binarize the image while taking into account the overall characteristics of the image. Otsu's method is especially effective when dealing with images with bimodal histograms, as it finds the optimal threshold between two peaks.

import cv2
from matplotlib import pyplot as plt
image = cv2.imread('22.jpg')
# 将输入图像转化成灰度图
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
# 绘制灰度图
plt.figure(figsize=(15, 15))
plt.subplot(311)
plt.imshow(gray,"gray")
plt.title("input image")
plt.xticks([])
plt.yticks([])
# 对灰度图使用Ostu法
ret1,th1 = cv2.threshold(gray,0,255,cv2.THRESH_OTSU)
# 绘制灰度直方图
plt.subplot(312)
plt.hist(gray.ravel(),256)
# 标注Ostu阀值所在直线
plt.axvline(x=ret1,color='red',label='otsu')
plt.legend(loc='upper right')
plt.title("Histogram")
plt.xticks([])
plt.yticks([])
# 绘制二值化图片
plt.subplot(313)
plt.imshow(th1,'gray')
plt.title("Output image")
plt.xticks([])
plt.yticks([])
plt.show()

For the image with two peaks in the gray histogram, the threshold value obtained by the Ostu algorithm is the position of the trough between the peaks, and the binarization effect is also relatively good; but when the size ratio of the target object and the background is very different or the gray level is close, resulting in three peaks in the histogram or a large gap between the two peaks, the Ostu algorithm cannot obtain satisfactory results. Because the gray distribution is used as the basis for setting the threshold, not only the result is extremely sensitive to noise, but also it is easy to lose the important spatial structure relationship in the image. In practical applications, it is generally used in combination with other methods.

Erosion, Dilation, Opening, Closing

For grayscale images, erosion and expansion operations are similar to convolution operations, which translate the structural elements on the original image, and the origin of the structural elements is equivalent to the kernel center of the convolution kernel. The opening and closing operations are the combination of the two. The opening operation is to corrode first and then expand, and the closing operation is to expand first and then corrode. Generally speaking, the open operation can smooth the contour of the image, disconnect narrow connections and eliminate fine burrs; the closed operation can also smooth the contour, but the specific function is to eliminate small holes, bridge narrow discontinuities, gullies and fill broken contour lines.

import cv2
import numpy as np
img = cv2.imread('22.jpg')
# 使用getStructuringElement 定义结构元素,shape 为结构元素形状,0表示矩形,1表示+字
k = cv2.getStructuringElement(shape=1,ksize=(3,3),anchor=(-1,-1))
# erode 腐蚀运算、src 输入图像、iterations 腐蚀操作次数
erosion = cv2.erode(src=img,kernel=k,iterations=1)
cv2.imshow('Eroded image',erosion)
# dilate 膨胀运算
dilation = cv2.dilate(img,k,iterations=1)
cv2.imshow('Dilated image',dilation)
# morphologyEx 实现开闭运算,op 运算类型,cv2.MORPH_OPEN 开运算 ,cv2.MORPH_CLOSE 闭运算
opening = cv2.morphologyEx(src=img,op=cv2.MORPH_OPEN,kernel=k)
closing = cv2.morphologyEx(src=img,op=cv2.MORPH_CLOSE,kernel=k)
cv2.imshow('Opening image',opening)
cv2.imshow('Closing image',closing)
cv2.imshow(' Image',img )
cv2.waitKey(0)
cv2.destroyAllWindows()

 

Guess you like

Origin blog.csdn.net/qq_31807039/article/details/131832460