如何使用Python+OpenCV正常高亮所有图像的轮廓?
解决OpenCV为多幅图像高亮轮廓的问题
需要处理的三张图像:
- 图像1:浅色背景上的深色手写数字
- 图像2:深色背景上的浅色手写数字
- 图像3:网格背景上的深色手写数字
你提供的原代码在第二张图像上失效的核心原因是固定阈值二值化无法适配不同亮度的图像——第二张图的前景与背景对比度、亮度分布和其他图差异明显,固定的120阈值无法生成正确的二值化结果,进而导致轮廓检测错误。
以下是适配所有三张图像的改进代码:
import cv2 import numpy as np def highlight_contour(image_path): # 读取图像 image = cv2.imread(image_path) if image is None: print(f"无法读取图像: {image_path}") return # 转为灰度图 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 高斯模糊降噪 gray = cv2.GaussianBlur(gray, (5, 5), 0) # 改用自适应阈值二值化,适配不同亮度的图像 thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # 形态学操作,去除小噪声点,强化轮廓完整性 kernel = np.ones((3,3), np.uint8) thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel) # 查找轮廓 cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if len(cnts) == 2 else cnts[1] # 过滤过小的噪声轮廓,只保留有效目标轮廓 valid_cnts = [c for c in cnts if cv2.contourArea(c) > 100] # 绘制所有有效轮廓(若仅需最大轮廓,可改为[c] = [max(valid_cnts, key=cv2.contourArea)]) if valid_cnts: cv2.drawContours(image, valid_cnts, -1, (0, 255, 0), 2) # 显示结果 cv2.imshow('高亮轮廓结果', image) cv2.waitKey(0) cv2.destroyAllWindows() # 替换为你的图像路径进行测试 highlight_contour("图像1路径.jpg") highlight_contour("图像2路径.jpg") highlight_contour("图像3路径.jpg")
关键改动说明:
- 自适应阈值替代固定阈值:使用
cv2.adaptiveThreshold,根据图像局部区域的亮度自动计算阈值,完美适配不同明暗分布的图像,解决第二张图的阈值不匹配问题。 - 形态学优化:通过闭运算填补轮廓内部小空隙,开运算去除背景噪声点,让二值化图像的轮廓更清晰完整。
- 轮廓过滤:添加面积过滤条件,忽略微小的噪声轮廓,确保只保留手写数字的轮廓。
- 批量处理封装:将逻辑封装为函数,方便一次性处理多幅图像。
期望实现的效果:在手写数字的边缘绘制绿色高亮轮廓,清晰包裹数字区域。
内容的提问来源于stack exchange,提问作者GameR
相关产品推荐
相关产品推荐

