Python OpenCV+imutils阅卷程序:无法识别整张试卷仅检测单个矩形
解决试卷轮廓检测与俯视图变换问题
你的问题核心是试卷边框较弱时,当前预处理流程没能有效提取整张试卷的轮廓,导致程序优先识别了内部面积较大的题目区域。可以通过优化预处理步骤、调整轮廓筛选逻辑来实现整张试卷的四顶点检测,具体方案如下:
关键改进点
- 替换Canny边缘检测为自适应阈值二值化:更适合处理光照不均、边框较弱的场景,能突出试卷的整体轮廓。
- 添加形态学闭操作:填充边缘间隙,强化试卷边框的连通性。
- 增加轮廓面积过滤:排除面积远小于试卷的小轮廓,避免干扰。
- 微调多边形近似的精度参数:适配弱边框的轮廓特征。
修改后的完整代码
# Import libraries import cv2 import numpy as np import imutils from imutils import contours from imutils.perspective import four_point_transform # 读取并预处理图像 image = cv2.imread("test4.jpg") # 缩放图像(可选,根据实际分辨率调整,便于处理) image = imutils.resize(image, height=800) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 用自适应阈值替代Canny,更适合弱边框场景 thresh = cv2.adaptiveThreshold( gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2 ) # 形态学闭操作:填充边框间隙,强化连通性 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) # 查找轮廓 cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours(cnts) docCnt = None # 筛选轮廓:优先找面积足够大的四边形 if len(cnts) > 0: # 按面积降序排序 cnts = sorted(cnts, key=cv2.contourArea, reverse=True) # 获取图像面积,设置最小面积阈值(比如图像的30%,可根据实际调整) image_area = image.shape[0] * image.shape[1] min_area = image_area * 0.3 for c in cnts: # 计算轮廓周长 peri = cv2.arcLength(c, True) # 调整近似精度(0.03*peri比0.02更宽松,适配弱边框) approx = cv2.approxPolyDP(c, 0.03 * peri, True) # 筛选条件:四边形+面积足够大 if len(approx) == 4 and cv2.contourArea(c) > min_area: docCnt = approx break # 执行透视变换(先判断是否找到有效轮廓) if docCnt is not None: paper = four_point_transform(image, docCnt.reshape(4, 2)) warped = four_point_transform(gray, docCnt.reshape(4, 2)) # 绘制试卷轮廓 cv2.drawContours(image, [docCnt], -1, (0, 255, 0), 3) cv2.imwrite("Contours.jpg", image) # 显示结果 cv2.imshow("Original with Contour", image) cv2.imshow("Top-Down View", paper) cv2.waitKey(0) cv2.destroyAllWindows() else: print("未检测到试卷轮廓,请调整预处理参数或检查图像")
代码解释
- 自适应阈值:通过
cv2.adaptiveThreshold根据局部区域的光照情况生成二值图像,能有效保留弱边框,避免Canny阈值固定导致的边缘丢失。 - 形态学闭操作:用矩形核填充边框的细小间隙,让试卷的轮廓更连贯,便于轮廓检测。
- 面积过滤:设置最小面积阈值为图像面积的30%,直接排除内部题目区域这类小轮廓,确保优先处理试卷本身。
- 多边形近似精度调整:将
0.02 * peri改为0.03 * peri,降低近似精度要求,更容易把弱边框的轮廓拟合为四边形。
如果试卷边框极不明显,还可以尝试以下额外优化:
- 调整自适应阈值的
blockSize(比如改为15)和C值(比如改为3),适配不同光照。 - 在形态学操作后添加一次膨胀操作,进一步强化边框。
- 尝试先对图像做灰度直方图均衡化(
cv2.equalizeHist(gray)),提升对比度后再做预处理。
内容的提问来源于stack exchange,提问作者mranonymous7122
相关产品推荐
相关产品推荐

