如何检测图像中已勾选复选框并提取关联文本?OpenCV代码故障求助
解决OpenCV无法检测已勾选复选框轮廓的问题
针对你遇到的无法检测已勾选复选框轮廓的问题,核心原因是原始代码提前过滤小轮廓时误删了勾选标记,且形态学操作破坏了复选框与勾选标记的边界。以下是调整后的解决方案:
关键修改思路
- 先检测所有复选框轮廓,不提前过滤小面积区域,避免误删勾选标记
- 对每个检测到的复选框单独分析内部区域,判断是否存在勾选内容
- 替换固定阈值为自适应阈值,适配表单可能存在的不均匀光照
调整后的代码
import cv2 import numpy as np # 加载灰度图像(替换为你的图像加载逻辑) gray = cv2.imread("form_area.png", cv2.IMREAD_GRAYSCALE) if gray is None: raise ValueError("无法加载目标图像") # 1. 预处理:自适应阈值适配不均匀光照 blur = cv2.GaussianBlur(gray, (5,5), 0) thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # 2. 检测所有复选框候选轮廓 cnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) checkbox_candidates = [] for c in cnts: peri = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.04 * peri, True) # 调整多边形近似系数 x, y, w, h = cv2.boundingRect(approx) # 根据表单实际尺寸过滤符合复选框特征的轮廓 aspect_ratio = w / float(h) if (len(approx) == 4 and 0.7 <= aspect_ratio <= 1.3 and 20 <= w <= 60 and 20 <= h <= 60): checkbox_candidates.append((x, y, w, h)) # 3. 逐个校验复选框是否被勾选 checked_boxes = [] for (x, y, w, h) in checkbox_candidates: # 提取复选框内部区域(避开边框) roi = thresh[y+2 : y+h-2, x+2 : x+w-2] # 统计内部非零像素数量(对应勾选标记) non_zero_count = cv2.countNonZero(roi) # 根据勾选样式调整阈值:内部10%以上有像素则判定为已勾选 if non_zero_count > (w * h) * 0.1: checked_boxes.append((x, y, w, h)) # 在原图上标记已勾选的复选框 cv2.rectangle(gray, (x, y), (x+w, y+h), (0, 0, 255), 2) print(f"检测到复选框总数: {len(checkbox_candidates)}") print(f"已勾选复选框数量: {len(checked_boxes)}") # 保存或查看结果 cv2.imwrite("marked_checkboxes.png", gray) cv2.imshow("Result", gray) cv2.waitKey(0) cv2.destroyAllWindows()
额外优化提示
- 尺寸范围调整:代码中
20 <= w <=60的数值需要根据你表单中复选框的实际大小修改 - 勾选阈值调整:
non_zero_count > (w*h)*0.1的比例可适配勾选样式——叉号可调低至0.05,实心方块可调高至0.2 - 预处理增强:若表单存在倾斜,可先做旋转校正;若有阴影,可添加
cv2.equalizeHist(gray)做直方图均衡化
内容的提问来源于stack exchange,提问作者Yishu Malhotra
相关产品推荐
相关产品推荐

