图像二值化就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。0为黑色, 1为白色
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)
print("threshold valye = %s"%ret)
cv.imshow("binary", binary)
def local_threshold(image): # 局部阈值
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
#自适应阈值化能够根据图像不同区域亮度分布,改变阈值
dst = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 25, 10)
cv.imshow("binary", dst)
def custom_threshold(image): # 手动计算均值
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
h, w = gray.shape[:2]
m = np.reshape(gray, [1, h*w]) # 将图像转为一维数组
mean = m.sum() / (h*w) # 手动求出均值
print("mean = ", mean)
ret, binary = cv.threshold(gray, mean, 255, cv.THRESH_BINARY)
print("ret = ", ret)
cv.imshow("binary", binary)
print("--------- Hello Python ---------")
src = cv.imread("D:/opencv/woman.jpeg")
cv.namedWindow("red", cv.WINDOW_AUTOSIZE)
cv.imshow("red", src)
custom_threshold(src)
cv.waitKey(0)
cv.destroyAllWindows()
threshold函数进行全局阈值,其函数原型为:
threshold(src, thresh, maxval, type[, dst]) -> retval, dst
src参数表示输入图像(多通道,8位或32位浮点)。
thresh参数表示阈值。
maxval参数表示与THRESH_BINARY和THRESH_BINARY_INV阈值类型一起使用设置的最大值。
type参数表示阈值类型。
retval参数表示返回的阈值。若是全局固定阈值算法,则返回thresh参数值。若是全局自适应阈值算法,则返回自适应计算得出的合适阈值。
dst参数表示输出与src相同大小和类型以及相同通道数的图像。
阈值类型:
type参数单独选择上述五种阈值类型时,是固定阈值算法,效果比较差。
此外还有自适应阈值算法:(自适应计算合适的阈值,而不是固定阈值)
比如结合cv.THRESH_OTSU,写成cv.THRESH_BINARY | cv.THRESH_OTSU。
例子:ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU) #大津法,全局自适应阈值,第二个参数值0可改为任意数字但不起作用。
THRESH_OTSU流程:
先计算图片的直方图
把直方图强度大于阈值的像素分成一组,把小于阈值的像素分成另一组
分别计算这两组的组内变异数,并把两个组内变异数相加
将0-255依序当作阈值来计算组内变异数和,总和值最小的就是结果阈值
比如结合cv.THRESH_TRIANGLE,写成cv.THRESH_BINARY | cv.THRESH_TRIANGLE。
例子:ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_TRIANGLE) #TRIANGLE法,全局自适应阈值,第二个参数值0可改为任意数字但不起作用,适用于单个波峰。
注意
cv.THRESH_OTSU和cv.THRESH_TRIANGLE也可单独使用,不一定要写成和固定阈值算法结合的形式。单独写和结合起来写,都是自适应阈值算法优先。
例子:ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_OTSU) #大律法 ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_TRIANGLE) #TRIANGLE法
adaptiveThreshold函数进行局部阈值,函数原型为:
adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]) -> dst
src参数表示输入图像(8位单通道图像)。
maxValue参数表示使用 THRESH_BINARY 和 THRESH_BINARY_INV 的最大值.
adaptiveMethod参数表示自适应阈值算法:平均 (ADAPTIVE_THRESH_MEAN_C)或高斯(ADAPTIVE_THRESH_GAUSSIAN_C)。
thresholdType参数表示阈值类型,必须为THRESH_BINARY或THRESH_BINARY_INV的阈值类型
blockSize参数表示块大小(奇数且大于1,比如3,5,7… )。
C参数是常数,表示从平均值或加权平均值中减去的数。 通常情况下,这是正值,但也可能为零或负值。
注意
在使用平均和高斯两种算法情况下,通过计算每个像素周围blockSize x blockSize大小像素块的加权均值并减去常量C即可得到自适应阈值。如果使用平均的方法,则所有像素周围的权值相同;如果使用高斯的方法,则每个像素周围像素的权值则根据其到中心点的距离通过高斯方程得到。
numpy的reshape函数是给数组一个新的形状而不改变其数据,函数原型:reshape(a, newshape, order=‘C’)