什么是图像预处理?
图像预处理的主要是消除图像中无关的信息,提高图像质量,增强有关信息的可检测性和最大限度地简化数据,从而让后续的特征抽取、图像分割等能够更好地进行
图像二值化
简单阈值或全局阈值
gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY) #把输入图像灰度化 // <!--把彩色三通道变成单通道,即化作为灰度图Gray=0.299⋅R+0.587⋅G+0.114⋅B--> ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)ret, binary = cv2.threshold(src, thresh, maxval, type)返回值有2个:
ret:本次使用的阈值,<!--这边是固定的阈值是127-->
binary:处理完成的二值图像
参数解释:
1、src:输入图像,必须是单通道灰度图(8 位 uint8 或 浮点数组)
2、thresh:手动设定的阈值分界值,像素以此为分界线判断大小
3、maxVal:最大阈值,一般为255. 注意:在THRESH_BINARY / THRESH_BINARY_INV两种模式下生效
4、type:阈值类型(有五类,见下方表格)
| 类型 | 大于阈值像素 | 小于等于阈值像素 | 输出特点 | 适用场景 |
|---|---|---|---|---|
| THRESH_BINARY | maxval(255) | 0 | 纯黑白二值 | 白底提取物体 |
| THRESH_BINARY_INV | 0 | maxval(255) | 纯黑白反转 | 黑底提取文字 |
| THRESH_TRUNC | thresh 原值 | 原图不变 | 多灰度、无纯白 | 压制高光过曝 |
| THRESH_TOZERO | 原图不变 | 0 | 保留高亮灰度 | 去除暗部噪点 |
| THRESH_TOZERO_INV | 0 | 原图不变 | 保留暗部灰度 | 去除强光反光 |
运行的代码:
import cv2 def image_binarization_demo(): # 1. 读取图像 # 注意:请将 'test.jpg' 替换为你电脑里的真实图片名称 # 如果图片和代码在同一文件夹,直接写名字即可 image = cv2.imread('test.jpg') if image is None: print("错误:找不到图片,请检查图片路径和名称是否正确!") return # 2. 将彩色图像转换为灰度图像 (对应博客第一行代码) #使用的是 RGB2GRAY,但在 cv2.imread 默认读取的是 BGR 格式,这里用 BGR2GRAY gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 彩色变成灰色单通道Gray=0.299⋅R+0.587⋅G+0.114⋅B # 3. 应用全局阈值进行二值化 # THRESH_BINARY 表示:大于127变白(255),小于127变黑(0) ret, final = cv2.threshold(gray, 127, 255,cv2.THRESH_TRUNC) print(ret) # 4. 显示处理前后的图像对比 cv2.imshow("Original Image", image) cv2.imshow("Grayscale Image", gray) cv2.imshow("final Image", final) # 5. 等待用户按任意键,然后关闭所有窗口 print("请在弹出的图片窗口上按键盘任意键关闭窗口...") cv2.waitKey(0) cv2.destroyAllWindows() if __name__ == "__main__": image_binarization_demo()运行结果:
cv2.THRESH_BINARY(黑白二值)
<!--图1是原图,图2是灰度图,图3是二值化图-->
cv2.THRESH_BINARY_INV(黑白二值反转)
cv2.THRESH_TRUNC
cv2.THRESH_TOZERO
cv2.THRESH_TOZERO_INV
自适应阈值
final= cv2.adaptiveThreshold( gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 21, 10 )dst = cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)6个参数介绍
1、src:输入图像:必须 单通道灰度图(uint8)
2、maxValue: 满足阈值条件后赋值的最大值,一般写255
3、adaptiveMethod :自适应算法
- cv2.ADAPTIVE_THRESH_MEAN_C小窗口内像素平均值作为该区域阈值
- cv2.ADAPTIVE_THRESH_GAUSSIAN_C小窗口内像素高斯加权平均值作为阈值,边缘更平滑,噪声更少,日常首选
4、thresholdType: 二值类型
cv2.THRESH_BINARY:局部大于阈值 → maxValue (255),否则 0cv2.THRESH_BINARY_INV:局部大于阈值 → 0,否则 255(文字提取常用)
5、blockSize:邻域窗口大小
规则:必须是大于 1 的奇数,常用:3,5,7,9,11
- 图像细节多、小字:3/5
- 大图、纹理粗:7/9 本质:以当前像素为中心,blockSize×blockSize 的方块计算局部阈值
6、C 常数偏移量:
最终局部阈值 = 区块计算出来的均值 / 高斯值 − C
- C=0:直接用均值当阈值
- C>0:阈值整体下调,更容易判定为白色(物体更容易被保留)
- C<0:阈值上调,更严苛 常用取值:2~10
运行代码:
import cv2 def image_binarization_demo(): # 1. 读取图像 # 注意:请将 'test.jpg' 替换为你电脑里的真实图片名称 # 如果图片和代码在同一文件夹,直接写名字即可 image = cv2.imread('test.jpg') if image is None: print("错误:找不到图片,请检查图片路径和名称是否正确!") return # 2. 将彩色图像转换为灰度图像 (对应博客第一行代码) #使用的是 RGB2GRAY,但在 cv2.imread 默认读取的是 BGR 格式,这里用 BGR2GRAY gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 彩色变成灰色单通道Gray=0.299⋅R+0.587⋅G+0.114⋅B # 3. 应用全局阈值进行二值化 # THRESH_BINARY 表示:大于127变白(255),小于127变黑(0) final= cv2.adaptiveThreshold( gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 21, 10 ) # 4. 显示处理前后的图像对比 cv2.imshow("Original Image", image) cv2.imshow("Grayscale Image", gray) cv2.imshow("final Image", final) # 5. 等待用户按任意键,然后关闭所有窗口 print("请在弹出的图片窗口上按键盘任意键关闭窗口...") cv2.waitKey(0) cv2.destroyAllWindows() if __name__ == "__main__": image_binarization_demo()运行结果:
全局阈值vs自适应阈值
| 对比维度 | 全局阈值 threshold () | 自适应阈值 adaptiveThreshold () |
|---|---|---|
| 阈值取值 | 全图共用 1 个固定阈值 | 每个局部区块独立生成阈值 |
| 光照适应性 | 差,明暗不均直接失效 | 强,完美处理渐变光影、阴影 |
| 输出图像 | 干净少噪点(均匀光) | 细节保留多,易产生细小噪点 |
| 计算速度 | 快 | 较慢 |
| 典型用途 | 均匀光照扫描图、纯色物体分割 | 手机实拍文字、逆光、阴影图片 |