基于OpenCV检测裁剪后复选框是否被勾选的实现疑问
基于OpenCV检测裁剪后复选框是否被勾选的实现疑问
嘿,看起来你已经搞定了复选框的定位和裁剪这一步,接下来判断是否有勾选标记(X、对勾、斜线等)其实可以从分析裁剪后区域的像素特征入手,这里给你几个实用的思路:
方法一:统计非空白像素占比
这是最直接的思路——勾选的复选框内部会有笔画,会比空框多出不少非背景色的像素。步骤如下:
- 先对裁剪后的复选框图像做灰度化和二值化,把背景转为白色(255),勾选标记转为黑色(0)
- 统计黑色像素的数量,和区域总像素数做比值,设置一个合理阈值(比如3%-5%),超过阈值就判定为已勾选
示例代码:
# 假设cropped_box是你裁剪好的单个复选框图像 gray = cv2.cvtColor(cropped_box, cv2.COLOR_BGR2GRAY) # 二值化:调整阈值适配你的图像,确保勾选标记变成黑色,背景为白色 _, binary = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY_INV) # 统计黑色像素数量 black_pixel_count = cv2.countNonZero(binary) total_pixels = binary.shape[0] * binary.shape[1] # 设定占比阈值,可根据实际图像调整 check_threshold = 0.03 if black_pixel_count / total_pixels > check_threshold: print("该复选框已勾选") else: print("该复选框未勾选")
方法二:轮廓检测(排除边框干扰)
如果你想更精准地识别内部的勾选标记,可以先把复选框的边框去掉,再检测内部的轮廓:
- 用你之前提取的边框二值图做掩膜,把边框区域从裁剪图中排除,只保留内部区域
- 对内部区域做二值化后检测轮廓,只要存在面积大于一定值的轮廓,就判定为已勾选
示例代码:
# 假设cropped_box是裁剪后的复选框图像,img_bin_final是你得到的边框二值图(白色边框,黑色背景) # 反转边框图,得到黑色边框、白色背景的掩膜 border_mask = cv2.bitwise_not(img_bin_final) # 用掩膜过滤掉边框,只保留内部区域 inner_area = cv2.bitwise_and(cropped_box, cropped_box, mask=border_mask) # 灰度化+二值化 gray_inner = cv2.cvtColor(inner_area, cv2.COLOR_BGR2GRAY) _, binary_inner = cv2.threshold(gray_inner, 200, 255, cv2.THRESH_BINARY_INV) # 检测外部轮廓 contours, _ = cv2.findContours(binary_inner, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 过滤掉噪声类的小轮廓 valid_contours = [cnt for cnt in contours if cv2.contourArea(cnt) > 20] if len(valid_contours) > 0: print("该复选框已勾选") else: print("该复选框未勾选")
另外补充一点:如果你调整裁剪坐标,只保留复选框的内部区域,那方法一会更简单——不需要处理边框,直接统计内部像素占比就行。阈值的设置建议多测试几个样本,根据你的图像清晰度、勾选标记的粗细来调整,找到最适配的数值。
备注:内容来源于stack exchange,提问作者carousallie
相关产品推荐
相关产品推荐

