如何使用Python检测并裁剪带边界线图像中的字符,排除多余边界?
代码修复方案
原代码核心问题
- 变量名错误:函数传入参数为
image,但代码中使用未定义的img创建副本 - 返回值错误:筛选后将全图阈值结果
thresh1加入返回列表,而非裁剪得到的数字区域 - 未过滤边缘轮廓:图像边界线必然贴合图像边缘,可通过坐标判断直接排除这类轮廓
- 空值返回逻辑缺失:过滤后无有效轮廓时未返回
None,而是返回空列表或者错误的边界结果
修正后完整代码
import cv2 # 若未实现sort_contours方法可使用以下兼容实现 def sort_contours(cnts, method="left-to-right"): reverse = False i = 0 if method == "right-to-left" or method == "bottom-to-top": reverse = True if method == "top-to-bottom" or method == "bottom-to-top": i = 1 boundingBoxes = [cv2.boundingRect(c) for c in cnts] (cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes), key=lambda b:b[1][i], reverse=reverse)) return (cnts, boundingBoxes) def process(image, readFile=True, returnType='binary'): img_h, img_w = image.shape[:2] out_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 阈值处理 ret, thresh1 = cv2.threshold(out_gray, 220, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY_INV) rect_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (8,8)) dilation = cv2.dilate(thresh1, rect_kernel, iterations = 1) # 提取最外层轮廓 contours, hierarchy = cv2.findContours(dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) if len(contours) <= 0: return None contours, boundingBoxes = sort_contours(contours, 'left-to-right') im2 = image.copy() minHeight = 10 minWidth = 10 result = [] for cnt in contours: x, y, w, h = cv2.boundingRect(cnt) # 过滤贴边的边界线:外接矩形和图像边缘重合则直接跳过 if x == 0 or y == 0 or (x + w) == img_w or (y + h) == img_h: continue # 过滤尺寸过小的噪点 if w < minWidth or h < minHeight: continue # 调试用的边框绘制可根据需求注释 cv2.rectangle(im2, (x, y-1), (x + w, y + h + 1), (0, 255, 0), 1) # 按返回类型裁剪对应区域 if returnType == 'binary': cropped = thresh1[y:y + h, x:x + w] else: cropped = image[y:y + h, x:x + w] result.append(cropped) # 无有效数字内容返回None return result if len(result) > 0 else None
关键优化说明
- 边缘轮廓过滤:提前获取图像宽高,所有外接矩形贴合图像边缘的轮廓都会被判定为边界线直接排除,不会进入后续筛选
- 返回逻辑修正:根据
returnType返回对应裁剪区域,不再返回全图阈值结果;无有效数字时直接返回None - 修复变量名错误:使用传入的
image参数创建图像副本,避免变量未定义报错
内容的提问来源于stack exchange,提问作者Hung Dang
相关产品推荐
相关产品推荐

