我用 Python 写了一个自动裁剪答题卡区域的小工具(附代码)

简介: 本文分享了一种通过 OpenCV 自动裁剪答题卡中答题区域的方法。核心思路是利用答题区域四周的黑色角块进行定位:先通过自适应阈值增强对比度,再用 `cv2.findContours()` 找轮廓,并计算每个轮廓的“紧凑度”(面积 / 周长)筛选出接近方块的角块。最终根据四个角块的边界矩形裁剪出答题区。代码实现详细,适合初学者参考,同时提供了参数调整建议以适配不同图像条件。

在做图像处理项目的时候,我遇到一个实际问题:怎么从一张拍下来的答题卡中,自动裁剪出答题区域?

答题区域其实很好识别 —— 通常被四个黑色小角块框住了。所以我写了一个简单的 OpenCV 脚本,试图通过这四个角块来定位并裁剪答题区域。

过程踩了点坑,但最终搞定了。以下是完整代码和我的思路,欢迎参考,也欢迎指正!

实现思路
我的目标是提取这类图像中的答题区:

利用自适应阈值,增强对比度;

通过 cv2.findContours() 找轮廓;

计算每个轮廓的面积和周长,用 面积 / 周长 计算“紧凑度”;

只保留紧凑度合理、形状接近方块的轮廓;

找到四个角块后,用它们的边界矩形裁剪出答题区。

代码如下

import cv2
import numpy as np
from typing import Optional

def extract_answer_area(image_path: str) -> Optional[np.ndarray]:
    """
    从图像中提取答题区域(通过四个黑色定位角块定位)
    使用紧凑度筛选角块
    """
    image = cv2.imread(image_path)
    if image is None:
        print(f"图像读取失败: {image_path}")
        return None

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)
    thresh = cv2.adaptiveThreshold(
        blurred, 255,
        cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
        cv2.THRESH_BINARY_INV, 11, 2
    )

    contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    rects = []
    for cnt in contours:
        area = float(cv2.contourArea(cnt))
        length = float(cv2.arcLength(cnt, True))
        if area <= 0 or length <= 0:
            continue
        compactness = area / length  # 紧凑度

        # 只选紧凑度在合理范围内的轮廓,值越大表示越“实心”、越接近方块
        if 5.5 < compactness < 7.5:
            print(compactness)
            approx = cv2.approxPolyDP(cnt, 0.02 * length, True)
            if len(approx) == 4:
                x, y, w, h = cv2.boundingRect(cnt)
                rects.append((x, y, w, h))

    print(f"共找到满足条件的角块数量: {len(rects)}")


    if len(rects) >= 4:
        xs = [x for (x, y, w, h) in rects] + [x + w for (x, y, w, h) in rects]
        ys = [y for (x, y, w, h) in rects] + [y + h for (x, y, w, h) in rects]
        x_min, x_max = min(xs), max(xs)
        y_min, y_max = min(ys), max(ys)

        cropped = image[y_min:y_max, x_min:x_max]
        return cropped
    else:
        print("未能识别到4个黑色角块请检查图像质量或参数。")
        return None


result = extract_answer_area(r"C:\Users\26950\Desktop\enghish1.jpg")

if result is not None:
    cv2.imwrite("answer_area_cropped.jpg", result)
    print("答题区已保存到 answer_area_cropped.jpg")
else:
    print("答题区提取失败")

切割前:enghish1.jpg

切割后:answer_area_cropped.jpg

关于“紧凑度”这个指标
我用的是 紧凑度 = 面积 / 周长,这个值可以用来排除线条、框线等细长的干扰物。

我观察到在我的图像中,角块的紧凑度大概集中在 5.5 到 7.5 左右,当然这可能和图像尺寸、拍摄角度有关。

如果你发现自己的图识别不到角块,可以:

打印出所有轮廓的 面积 / 周长 看看;

调整这两个阈值;

也可以加上其他筛选,比如面积范围、是否是矩形等。

补充说明
之后可以把答题卡上的题目按照题型分类后来批改,可以尝试使用ocr或者具有视觉能力的大模型

目录
相关文章
|
人工智能
基于qwen2和qwenvl的自动批改作业应用!
针对作业批改中常见的问题,如低质量作业、大量简单作业耗时、需初筛异常作业等,开发了一款自动批改作业的应用。该应用通过备份作业文件、获取文档内容、利用AI生成评语,并保存关键信息与日志,简化了教师的工作流程,提高了效率。应用设计简洁,易于扩展,支持图片转文字处理,适合教育场景使用。
4751 1
基于qwen2和qwenvl的自动批改作业应用!
|
机器学习/深度学习 人工智能 数据可视化
图解Transformer——注意力计算原理
图解Transformer——注意力计算原理
851 0
|
6月前
|
存储 弹性计算 缓存
2026年阿里云幻兽帕鲁(Palworld)一键部署全攻略,轻松搭建专属联机服务器!
《幻兽帕鲁》爆火,阿里云2026年推出一键部署联机服务器方案:零基础玩家3分钟即可搭建专属服,支持1–32人联机,自动配置、存档备份、深度自定义一应俱全,低延迟、高稳定,轻松当“服主”!
1130 2
|
9月前
|
算法 物联网 机器人
蓝牙信标、UWB等主流室内定位无线技术的参数对比、核心算法和选型指南详解(二)
本文系统解析室内定位无线技术,涵盖蓝牙、Wi-Fi、UWB、RFID、超声波、可见光等主流技术的原理、参数对比与核心算法(RSSI、TDOA、AoA),并提供按精度、成本、场景匹配的选型指南,助力民用、工业、资产盘点及特殊环境下的最优技术选择。如果您想进一步了解定位的案例,欢迎关注、评论留言~也可搜索lbs智能定位。
|
运维 Linux Apache
Puppet这一强大的自动化运维工具,涵盖其基本概念、安装配置及使用示例
【10月更文挑战第8天】本文介绍了Puppet这一强大的自动化运维工具,涵盖其基本概念、安装配置及使用示例。Puppet通过定义资源状态和关系,确保系统配置始终如一,支持高效管理基础设施。文章详细讲解了Puppet的安装步骤、配置方法及DSL语言示例,帮助读者快速掌握Puppet的使用技巧。
1370 2
|
JavaScript 前端开发
js时间戳转日期时间
js时间戳转日期时间
923 76
|
人工智能 自然语言处理 搜索推荐
gemini国内能用吗?请收下这份gemini使用攻略!
在当今技术迅猛发展的时代,人工智能(AI)语言模型已经成为一股变革性的力量,推动着从自然语言处理到对话生成等广泛应用领域的创新。在众多杰出的AI语言模型中,Gemini以其卓越的性能和广泛的用途脱颖而出,备受推崇。作为谷歌旗下的多模态AI巨头,Gemini融合了最先进的语言处理技术,为用户提供了无与伦比的语言理解和生成能力。
基于PP-Structure急速 30行代码实现表格识别
基于PP-Structure急速 30行代码实现表格识别
1544 0
基于PP-Structure急速 30行代码实现表格识别
|
Kubernetes Cloud Native Linux
如何使用 Containerfile/Dockerfile 构建 .net 镜像?
构建轻量级的 .NET Core 镜像通常涉及到几个关键步骤,主要是选择正确的基础镜像、使用多阶段构建、优化文件结构以及清理不必要的文件。.NET 8 在云原生方面的支持有了显著的增强,这些改进旨在提高性能、减少资源消耗、简化部署流程以及提升应用程序的可观察性和可维护性。
1589 5
如何使用 Containerfile/Dockerfile 构建 .net 镜像?
|
前端开发 JavaScript
图片区域点击处理
【10月更文挑战第25天】在前端开发中,图片区域点击处理可通过 HTML、CSS 和 JavaScript 实现。首先创建包含图片的 HTML 元素,使用 CSS 调整样式,再通过 JavaScript 获取图片元素并添加点击事件监听器,根据点击坐标判断区域,实现特定功能。也可借助 Paper.js 或 Fabric.js 等库简化开发。
692 2

热门文章

最新文章