OpenCV二值化处理光照不均图像无法准确保留铅笔填涂气泡如何解决
OpenCV二值化处理填涂图光照不均问题方案
问题场景
使用OpenCV阈值函数处理铅笔填涂类图像生成二值图时,出现两类效果冲突:
- 直接使用Otsu阈值法:受局部光照差异影响,二值图存在大量杂色白色斑块,效果如下:

- 换用自适应阈值法:虽能缓解光照不均带来的斑块问题,但Otsu法原本可以正确识别的铅笔填涂气泡区域无法完整呈现,效果如下:

- 处理目标:修正光照不均、消除杂色斑块的同时,准确还原铅笔填涂的气泡区域
- 待处理原始图像:

- 原有实现代码:
#binary image conversion thresh2 = cv2.adaptiveThreshold(papergray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 21, 13) thresh = cv2.threshold(papergray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1] cv2.imshow("Binary", thresh) #Otsu's cv2.imshow("Adpative",thresh2)
解决步骤
两种方法效果顾此失彼,本质是没提前做光照校正预处理,且自适应阈值参数和填涂区域尺寸不匹配,按以下流程处理即可达到预期效果:
- 光照校正预处理
光照不均属于图像的低频亮度变化,使用大尺寸高斯模糊提取全图亮度背景,再用原图除以背景层即可拉平全图亮度,从根源消除局部过亮过暗的问题。注意高斯核尺寸必须大于图中最大的填涂气泡,否则会把气泡本身识别为背景滤除,针对这张测试图用101*101的核(必须为奇数)即可:import cv2 import numpy as np # 读取灰度图像 papergray = cv2.imread("sheet.jpg", 0) # 大核高斯模糊提取光照背景 bg = cv2.GaussianBlur(papergray, (101, 101), 0) # 做亮度校正得到光照均匀的图像 corrected = cv2.divide(papergray, bg, scale=255) - 二值化处理
校正后的图像亮度均匀,直接使用Otsu阈值法就不会出现大块杂色斑块,填涂区域也能完整保留:
如果偏好使用自适应阈值,将原参数中的邻域块大小调至和气泡尺寸匹配(如51),调低偏移值,同时将均值自适应改为高斯自适应,避免边缘识别破碎:# 光照校正后跑Otsu _, thresh_otsu = cv2.threshold(corrected, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)thresh_adap = cv2.adaptiveThreshold(corrected, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 51, 8) - 可选后处理去噪
如果二值图中还有少量细碎噪点,用3*3的核对二值图做一次形态学开运算即可清除,不会破坏填涂气泡的完整轮廓:kernel = np.ones((3,3), np.uint8) final_thresh = cv2.morphologyEx(thresh_otsu, cv2.MORPH_OPEN, kernel)
提示:如果处理的图像分辨率变化,对应调整高斯核、自适应阈值块的大小即可,核心原则是核尺寸要大于单个填涂气泡的尺寸。
内容的提问来源于stack exchange,提问作者Joshua Yang
相关产品推荐
相关产品推荐

