图像的二值化
- 图像的二值化:就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果。基于图像的直方图来实现的,0白色 1黑色
- 一幅图像包括目标物体、背景还有噪声,要想从多值的数字图像中直接提取出目标物体,常用的方法就是设定一个阈值T,用T将图像的数据分成两部分:大于T的像素群和小于T的像素群。这是研究灰度变换的最特殊的方法,称为图像的二值化(Binarization)
阈值
- 阈值又叫临界值,是指一个效应能够产生的最低值或最高值。
- 在图像处理中它的意思是颜色转换的临界点,该方法只用于二值化的图像中;如在自然中每一种颜色都有一个值,通常由RGB(即红、绿、蓝三原色)按比例混合就会得到各种不同的颜色。阈值处理图片是对颜色进行特殊处理的一种方法。
- 详细说,阈值是一个转换临界点,不管你的图片是什么样的彩色,它最终都会把图片当黑白图片处理; 也就是说你设定了一个阈值之后,它会以此值作标准,凡是比该值大的颜色就会转换成白色,低于该值的颜色就转换成黑色,所以最后的结果是,你得到一张黑白的图片。
- 用阈值的作用:得到一张对比度不同的黑白图片。阈值可以是最小值:某一性能特征不能低于该值
一、全局阈值
cv2.threshold(src, thresh, maxval, type[, dst]) |
-
src:表示的是图片源
-
thresh:表示的是阈值(起始值)
-
maxval:表示的是最大值
-
type:表示的是这里划分的时候使用的是什么类型的算法,常用值为0(cv2.THRESH_BINARY)
-
对于最后一个参数,常见的阈值类型有:
THRESH_BINARY=0,THRESH_BINARY_INV,THRESH_TRUNC,THRESH_TOZERO,THRESH_TOZERO_INV,THRESH_OTSU,THRESH_TRIANGLE,THRESH_MASK函数threshold()的参数说明:
cv.THRESH_BINARY | cv.THRESH_OTSU)#大律法,全局自适应阈值 参数0可改为任意数字但不起作用 cv.THRESH_BINARY | cv.THRESH_TRIANGLE)#TRIANGLE法,,全局自适应阈值, 参数0可改为任意数字但不起作用,适用于单个波峰 cv.THRESH_BINARY)# 自定义阈值为150,大于150的是白色 小于的是黑色 cv.THRESH_BINARY_INV)# 自定义阈值为150,大于150的是黑色 小于的是白色 cv.THRESH_TRUNC)# 截断 大于150的是改为150 小于150的保留 cv.THRESH_TOZERO)# 截断 小于150的是改为150 大于150的保
-
-
函数返回值:第一个是阈值(T),第二个是处理过后的图像
def threshold_image(image):
gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY)
cv.namedWindow('image', cv.WINDOW_NORMAL)
cv.imshow('image', gray)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU) # 大律法,全局自适应阈值,参数0可改成任意数字但不起作用
print("阈值:%s" % ret)
cv.namedWindow('OTSU', cv.WINDOW_NORMAL)
cv.imshow("OTSU", binary)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_TRIANGLE) # TRIANGLE法,全局自适应阈值,参数0可改为任意数字,但不起作用,适用于单个峰波
print("阈值:%s" % ret)
cv.namedWindow('TRIANGLE', cv.WINDOW_NORMAL)
cv.imshow("TRIANGLE", binary)
ret, binary = cv.threshold(gray, 150, 255, cv.THRESH_BINARY) # 自定义阈值为150 大于150的是白色,小于150的是黑色
print("阈值:%s" % ret)
cv.namedWindow('zidingyi', cv.WINDOW_NORMAL)
cv.imshow("zidingyi", binary)
ret, binary = cv.threshold(gray, 150, 255, cv.THRESH_BINARY_INV) # 自定义阈值为150 大于150的是黑色,小于150是白色
print("阈值:%s" % ret)
cv.namedWindow('zidingyifanse', cv.WINDOW_NORMAL)
cv.imshow("zidingyifanse", binary)
ret, binary = cv.threshold(gray, 150, 255, cv.THRESH_TRUNC) # 截断大于150的更改为150, 小于150的保留
print("阈值:%s" % ret)
cv.namedWindow('jieduan1', cv.WINDOW_NORMAL)
cv.imshow("jieduan1", binary)
ret, binary = cv.threshold(gray, 150, 255, cv.THRESH_TOZERO) # 截断小于150的更改为150, 大于150的保留
print("阈值:%s" % ret)
cv.namedWindow('jieduan2',cv.WINDOW_NORMAL)
cv.imshow("jieduan2", binary)
src = cv.imread('./static/image/blur.jpg')
threshold_image(src)
cv.waitKey(0)
cv.destroyAllWindows()
运行结果:
二、局部阈值
自适应阈值二值化函数根据图片一小块区域的值来计算对应区域的阈值,从而得到也许更为合适的图片。
dst = cv2.adaptiveThreshold(src, maxval, thresh_type, type, Block Size, C) |
- dst: 输出图
- src: 输入图,只能输入单通道图像,通常来说为灰度图
- maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
- thresh_type: 阈值的计算方法,包含以下2种类型:cv2.ADAPTIVE_THRESH_MEAN_C; cv2.ADAPTIVE_THRESH_GAUSSIAN_C.
- type:二值化操作的类型,与固定阈值函数相同,包含以下5种类型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV.
- Block Size: 图片中分块的大小
- C :阈值计算方法中的常数项
代码如下:
def local_image(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.namedWindow("image", cv.WINDOW_NORMAL)
cv.imshow("image", gray)
binary1 = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 25, 10)
cv.namedWindow("image1", cv.WINDOW_NORMAL)
cv.imshow("image1", binary1)
cv.imwrite("./img/H11-1.jpg", binary1)
binary2 = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 25, 10)#高斯处理
cv.namedWindow("image2", cv.WINDOW_NORMAL)
cv.imshow("image2", binary2)
cv.imwrite("./img/H11-2.jpg", binary2)
src = cv.imread("./static/image/windows.jpg")
local_image(src)
cv.waitKey(0)
cv.destroyAllWindows()
运行效果:
三、求图像平均阈值
求出图像均值作为阈值来二值化
def custom_image(image):
gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY)
cv.namedWindow('image', cv.WINDOW_NORMAL)
cv.imshow("image", gray)
h, w = gray.shape[:2]
m = np.reshape(gray, [1, w*h]) # 化为一维数组
mean = m.sum() / (w*h)
print("mean: ", mean)
ret, binary = cv.threshold(gray, mean, 255, cv.THRESH_BINARY)
cv.namedWindow("twoValue", cv.WINDOW_NORMAL)
cv.imshow('twoValue', binary)
src = cv.imread('./static/image/blur.jpg')
custom_image(src)
cv.waitKey(0)
cv.destroyAllWindows()
运行效果: