图像的二值化

图像的二值化

图像二值化( Image Binarization)就是将图像上的像素点的灰度值设置为0255,也就是将整个图像呈现出明显的黑白效果的过程。

在数字图像处理中,二值图像占有非常重要的地位,图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。

1
所使用的阈值,结果图片 = cv.threshold(img,阈值,最大值,类型)

THRESH_BINARY 高于阈值改为255,低于阈值改为0
THRESH_BINARY_INV 高于阈值改为0,低于阈值改为255
THRESH_TRUNC 截断,高于阈值改为阈值,最大值失效
THRESH_TOZERO 高于阈值不改变,低于阈值改为0
THRESH_TOZERO_INV 高于阈值该为0,低于阈值不改变

简单阈值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import cv2 as cv

# 读取图像
img = cv.imread("assets/car.jpg",cv.IMREAD_GRAYSCALE)
# 显示图片
cv.imshow("gray",img)
# 获取图片信息
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]

# 定义阈值
thresh = 60

for row in range(height):
    for col in range(width):
        # 获取当前灰度值
        grayValue = img[row,col]
        if grayValue>thresh:
            img[row,col]=255
        else:
            img[row,col]=0

# 直接调用api处理 返回值1:使用的阈值, 返回值2:处理之后的图像
# ret,thresh_img = cv.threshold(img, thresh, 255, cv.THRESH_BINARY)

# 显示修改之后的图片
cv.imshow("thresh",img);

cv.waitKey(0)
cv.destroyAllWindows()

自适应阈值

我们使用一个全局值作为阈值。但是在所有情况下这可能都不太好,例如,如果图像在不同区域具有不同的照明条件。在这种情况下,自适应阈值阈值可以帮助。这里,算法基于其周围的小区域确定像素的阈值。因此,我们为同一图像的不同区域获得不同的阈值,这为具有不同照明的图像提供了更好的结果。

除上述参数外,方法cv.adaptiveThreshold还有三个输入参数:

adaptiveMethod决定阈值是如何计算的:

  • cv.ADAPTIVE_THRESH_MEAN_C:该阈值是该附近区域减去恒定的平均Ç
  • cv.ADAPTIVE_THRESH_GAUSSIAN_C:阈值是邻域值减去常数C的高斯加权和。

BLOCKSIZE确定附近区域的大小和Ç是从平均值或附近的像素的加权和中减去一个常数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import cv2 as cv

# 读取图像
img = cv.imread("assets/thresh1.jpg",cv.IMREAD_GRAYSCALE)
# 显示图片
cv.imshow("gray",img)
# 获取图片信息
imgInfo = img.shape

# 直接调用api处理 参数1:图像数据 参数2:最大值  参数3:计算阈值的方法, 参数4:阈值类型 参数5:处理块大小  参数6:算法需要的常量C
thresh_img = cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY,11,5)

# 显示修改之后的图片
cv.imshow("thresh",thresh_img);

cv.waitKey(0)
cv.destroyAllWindows()

THRESH_OTSU

采用日本人大津提出的算法,又称作最大类间方差法,被认为是图像分割中阈值选取的最佳算法,采用这种算法的好处是执行效率高!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import cv2 as cv

# 读取图像
img = cv.imread("assets/otsu_test.png",cv.IMREAD_GRAYSCALE)
cv.imshow("src",img)

ret,thresh_img = cv.threshold(img, 225, 255, cv.THRESH_BINARY_INV)
cv.imshow("normal", thresh_img);

gaussian_img = cv.GaussianBlur(img,(5,5),0)
cv.imshow("g",gaussian_img)

ret,thresh_img = cv.threshold(gaussian_img, 0, 255, cv.THRESH_BINARY|cv.THRESH_OTSU)
cv.imshow("otsu", thresh_img);

print("阈值:",ret)
cv.waitKey(0)
cv.destroyAllWindows()