阴影环境下,如何生成适配7段数码管数字提取的二值图?
问题描述
正在开展7段数码管数字提取项目,已成功提取LED显示屏的ROI,但在阴影环境下难以生成合适的二值图像,无法用cv2.findContours准确识别数字。现有处理后的二值图效果不佳,数字的部分笔画丢失。
原始照片:
提取后的黑白照片:
现有代码:
img_name = 'test2.jpeg' image = cv2.imread(img_name) image = imutils.resize(image, height=1000) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (5, 5), 0) edged = cv2.Canny(blurred, 50, 200, 255) #cv2.imshow("test", edged) #cv2.waitKey(0) cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours(cnts) cnts = sorted(cnts, key=cv2.contourArea, reverse=True) displayCnt = None # loop over the contours for c in cnts: # approximate the contour peri = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.02 * peri, True) # if the contour has four vertices, then we have found # the thermostat display if len(approx) == 4: displayCnt = approx break warped = four_point_transform(gray, displayCnt.reshape(4, 2)) output = four_point_transform(image, displayCnt.reshape(4, 2)) thresh = cv2.threshold(warped, 222, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)[1] cv2.imwrite("black.png", thresh)
阴影环境下的二值化优化方案
阴影导致图像局部亮度差异大,全局阈值(如OTSU)易失效,可尝试以下方法:
1. 自适应阈值二值化
基于局部区域计算阈值,适配明暗不均场景,替换原阈值代码:
# blockSize取奇数,C为阈值调整常数,可根据效果微调 thresh = cv2.adaptiveThreshold(warped, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
2. 光照补偿+阈值处理
先提升局部对比度,再做阈值:
- 直方图均衡化:
equalized = cv2.equalizeHist(warped) thresh = cv2.threshold(equalized, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
- CLAHE(限制对比度自适应均衡化,避免噪声过度增强):
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) equalized = clahe.apply(warped) thresh = cv2.threshold(equalized, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
3. 颜色通道分离处理
若数字为特定颜色(如红色),提取对应通道处理更抗干扰:
import numpy as np # 基于彩色ROI(对应代码中的output)处理 hsv = cv2.cvtColor(output, cv2.COLOR_BGR2HSV) # 红色HSV范围,需根据实际场景微调 lower_red1 = np.array([0, 120, 70]) upper_red1 = np.array([10, 255, 255]) lower_red2 = np.array([170, 120, 70]) upper_red2 = np.array([180, 255, 255]) mask = cv2.inRange(hsv, lower_red1, upper_red1) | cv2.inRange(hsv, lower_red2, upper_red2) # 形态学操作修复细节 kernel = np.ones((3,3), np.uint8) thresh = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
4. 形态学优化
二值化后用膨胀+腐蚀修复断裂笔画:
kernel = np.ones((2,2), np.uint8) thresh = cv2.dilate(thresh, kernel, iterations=1) thresh = cv2.erode(thresh, kernel, iterations=1)
内容的提问来源于stack exchange,提问作者Chak Wing Mak
相关产品推荐
相关产品推荐

