本文使用python实现。
全局阈值
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)
'''
# 函数 cvThreshold 对单通道数组应用固定阈值操作。该函数的典型应用是对灰度图像进行阈值操作得到二值图像。
def threshold(src: Any, # 原图像
thresh: Any, # 设定的阈值
maxval: Any, # 使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值
type: Any, # threshold_type
dst: Any = None) -> None
本函数支持的对图像取阈值的方法由 threshold_type 确定:
threshold_type=CV_THRESH_BINARY:
dst(x,y) = max_value, if src(x,y)>threshold 0, otherwise.
threshold_type=CV_THRESH_BINARY_INV:
dst(x,y) = 0, if src(x,y)>threshold; dst(x,y) = max_value, otherwise.
threshold_type=CV_THRESH_TRUNC:
dst(x,y) = threshold, if src(x,y)>threshold; dst(x,y) = src(x,y), otherwise.
threshold_type=CV_THRESH_TOZERO:
dst(x,y) = src(x,y), if (x,y)>threshold ; dst(x,y) = 0, otherwise.
threshold_type=CV_THRESH_TOZERO_INV:
dst(x,y) = 0, if src(x,y)>threshold ; dst(x,y) = src(x,y), otherwise.
类型中有个参数:CV_THRESH_OTSU是提取图像最佳阈值算法。该方法在类间方差最大的情况下是最佳的,就图像的灰度值而言,OTSU给出最好的类间分离的阈值。
OpenCV阈值分割的几种方法:
CV_THRESH_BINARY =0, value = value > threshold ? max_value : 0
CV_THRESH_BINARY_INV =1, value = value > threshold ? 0 : max_value
CV_THRESH_TRUNC =2, value = value > threshold ? threshold : value
CV_THRESH_TOZERO =3, value = value > threshold ? value : 0
CV_THRESH_TOZERO_INV =4, value = value > threshold ? 0 : value
CV_THRESH_MASK =7,
CV_THRESH_OTSU =8 采用Otsu算法选择最优阈值;将该标志与上面的一个CV_THRESH_*值或起来
'''
print("threshold value %s"%ret)
cv.imshow("threshold_demo", binary)
src = cv.imread("C:/Users/admin/Pictures/Saved Pictures/7.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
threshold_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
效果
局部二值化
def local_threshold(image): # 局部二值化
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
binary = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 25, 10)
'''
def adaptiveThreshold(src: Any, # 原始图像
maxValue: Any, # 预设满足条件的最大值
adaptiveMethod: Any, # 指定自适应阈值算法。
thresholdType: Any, # 指定阈值类型:可选择THRESH_BINARY或者THRESH_BINARY_INV两种。(即二进制阈值或反二进制阈值)。
blockSize: Any, # 表示邻域块大小,用来计算区域阈值,一般选择为3、5、7......等奇数。
C: Any, # 参数C表示与算法有关的参数,它是一个从均值或加权均值提取的常数,可以是负数。
dst: Any = None) -> None
其中指定自适应阈值算法参数 adaptiveMethod :
可选择ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C两种。
ADAPTIVE_THRESH_MEAN_C,为局部邻域块的平均值。该算法是先求出块中的均值,再减去常数C。
ADAPTIVE_THRESH_GAUSSIAN_C ,为局部邻域块的高斯加权和。该算法是在区域中(x,y)周围的像素根据高斯函数按照他们离中心点的距离进行加权计算,再减去常数C。
'''
cv.imshow("local_threshold", binary)
效果
超大图像局部二值化
def big_image_binary(image):
print(image.shape)
cw = 256
ch = 256
h, w = image.shape[:2]
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
for row in range(0, h, ch):
for col in range(0, w, cw):
roi = gray[row:row+ch, col:cw+col]
dst = cv.adaptiveThreshold(roi, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 127, 20)
gray[row:row+ch, col:cw+col] = dst
print(np.std(dst), np.mean(dst))
cv.imwrite("C:/Users/admin/Desktop/18_2.jpg", gray)
这里使用的大图,我只能缩小了再放上来: