SkillAgentSearch skills...

OCRAutoScore

OCR自动化阅卷项目

Install / Use

/learn @vkgo/OCRAutoScore
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

OCRAutoScore

此仓库为大创集成仓库的README介绍资料。仓库用于将各模块按照流程图一个个完成,并留下输入输出相关接口、文档。README用于说明此项目的原理、实现方式、复现方法等。

GitHub仓库地址:https://github.com/vkgo/OCRAutoScore

1 总流程图

系统流程图

2 模块开发规范

示例,如scoreblocks/fillblankmodel.py文件一样,写一个类,实际操作中,我们实例化这个类,然后在这个类的init中加载各使用到的模型(后面就不用每次调用都要加载了),然后使用类中各个成员函数来实现功能。而py文件中的if __name__ == "__main__":可以用来测试用。类、函数的注释中英文都行。

import paddleocr
import numpy as np
from PIL import Image
import torch
from transformers import CLIPProcessor, CLIPModel

debug = False

class model:
    def __init__(self, language:str="en"):
        """
        :parameter language: the language of the text, `ch`, `en`, `french`, `german`, `korean`, `japan`, type: str
        """
        self.ocr = paddleocr.PaddleOCR(use_angle_cls=True, lang=language)
        self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
        self.clip_model = CLIPModel.from_pretrained("openai/clip-vit-large-patch14").to(self.device)
        self.clip_processor = CLIPProcessor.from_pretrained("openai/clip-vit-large-patch14", device=self.device)

    def recognize_text(self, _img:Image):
        """
        Predict the text from image
        :parameter img: image, type: np.ndarray
        :return: result, type: tuple{location: list, text: str}
        """
        img = np.array(_img)
        result = self.ocr.ocr(img)
        if debug:
            print(result)
        if len(result[0]) == 0:
            return None
        else:
            location = result[0][0][0]
            text = result[0][0][1][0]
            return (location, text)

    def judge_with_clip(self, _answer:str, _predict:str, _img:Image):
        """
        Use clip to judge which one is more similar to the Image
        :parameter answer: the answer text, type: str
        :parameter predict: the predict text, type: str
        :parameter img: image, type: np.ndarray
        :return: result, the index of the more similar text, type: int
        """
        image = _img
        inputs = self.clip_processor(text=[f"A picture with the text \"{_answer}\"", f"A picture with the text \"{_predict}\"",
                                 "A picture with the other text"], images=image, return_tensors="pt", padding=True)
        inputs.to(self.device)

        outputs = self.clip_model(**inputs)
        logits_per_image = outputs.logits_per_image  # this is the image-text similarity score
        probs = logits_per_image.softmax(dim=1)  # we can take the softmax to get the label probabilities
        if debug:
            print(probs)
        index = torch.argmax(probs, dim=1)
        return index

if __name__ == "__main__":
    """
    用于测试函数
    """
    debug = True
    import paddle
    print(paddle.device.is_compiled_with_cuda())
    model = model()
    while True:
        img_path = input("请输入图片路径: ")
        answer = input("请输入正确答案: ")
        img = Image.open(img_path)
        predict = model.recognize_text(img)[1]
        print("预测结果: ", predict)
        if (predict != answer):
            print("正确结果:", answer)
            index = model.judge_with_clip(answer, predict, img)
            print("判断结果: ", (answer, predict, "error")[index])

3 文件目录说明

OCRAutoScore
+----scoreblocks # 填空题、选择题、作文的批改模型文件夹
|    CharacterRecognition
|    |    +----SpinalVGG.pth # SpinalVGG模型
|    |    +----WaveMix.pth # WaveMix模型
|    |    +----example # 测试图片
|    fillblank_testdata # 填空题测试图片
|    MSPLM # AES模型 
|    +----essayscoremodel.py # 作文评分模型
|    +----fillblankmodel.py # 填空题批改模型
|    +----singleCharacterRecognition.py # 单字母识别模型
+----score_web # 前端网页文件夹
|    | components # 前端组件
|    | pages # 页面
|    | routes # 路由
+----score_server # 后端文件夹
|    |  index
|    +----models.py # 数据库模型
|    +----urls.py # 接口文件
|    +----views.py # 视图处理函数
+----CAN # 共识识别 CAN模型的部分依赖
+----README.assets # README的图片文件夹
+----README.md # 仓库说明文件
+----.gitignore # git忽略的文件夹、文件

4 作答区域分割-大题分割

在大题分割部分,我们使用了YOLOv8模型,通过使用老师提供的数据集进行训练,最终呈现了十分完美的效果。

4.1 YOLOv8

<img src="README.assets/62b5ed8625d6c4a157f1ee7a1c10c4e9.png" alt="YOLOv8来啦 | 详细解读YOLOv8的改进模块!YOLOv5官方出品YOLOv8,必卷! - 智源社区" style="zoom: 67%;" />

YOLOv8是一个包括了图像分类、Anchor-Free物体检测和实例分割的高效算法,检测部分设计参考了目前大量优异的最新的YOLO改进算法,实现了新的SOTA。YOLOv8抛弃了前几代模型的Anchor-Base,是一种基于图像全局信息进行预测的目标检测系统。

与前代相比,YOLOv8有以下不同:

  1. 提供了全新的SOTA模型,包括具有P5 640和P6 1280分辨率的目标检测网络以及基于YOLACT的实例分割模型。与YOLOv5类似,还提供了不同大小的N/S/M/L/X比例模型,根据缩放系数来满足不同场景需求。

  2. 骨干网络和Neck部分可能参考了YOLOv7 ELAN的设计思路。在YOLOv5中,C3结构被替换为具有更丰富梯度流动性的C2f结构。对于不同比例模型进行了不同通道数量调整,并经过精心微调而非盲目应用一组参数到所有模型上,大大提高了模型性能。然而,在这个C2f模块中存在一些操作(如Split)并不像之前那样适合特定硬件部署。

  3. 与YOLOv5相比,在Head部分进行了重大改变,采用主流解耦头结构将分类和检测头分离,并从Anchor-Based转向Anchor-Free。

  4. 在损失计算策略方面,采用TaskAlignedAssigner正样本分配策略以及引入Distribution Focal Loss。

  5. 在训练过程中进行数据增强时,引入自YOLOX关闭Mosaic增强操作后10个epoch可以有效提高准确性。

YOLOv8作为一种实时目标检测算法,可能被应用于多种场景,包括但不限于:

  • 无人驾驶汽车:实时检测道路上的行人、车辆、交通信号等目标,为自动驾驶系统提供关键信息。
  • 视频监控:实时检测和跟踪安全系统中的异常行为,如闯入、偷窃等。
  • 工业自动化:用于产品质量检测、机器人导航等领域。
  • 无人机航拍:实时目标检测和跟踪,为无人机提供导航和避障能力。

此处,我们将其应用于大题分割,也就是,在我们提供的整张试卷中,找到对应的大题(如:客观题、填空题、主观题等)。

4.2 单独执行大题分割

大题分割源码在segmentation/Layout4Card,也可以通过URL进入我们仓库中大题分割的目录查看、复制、运行,需要更多的支持,可以查看文档

infer.py是一个推理代码的示范,在这之中:

  1. CLS_ID_NAME_MAP是一个字典,里面有我们支持的识别类别和它对应的index。
  2. model是载入模型,此处可以使用我们训练好的模型不需要改动。
  3. folder是将要测试的图片的目录,可以换为测试图片。
  4. 运行后,由于model.predict(source=imgs, save=True, imgsz=640)中的save=True,文件将被村粗在segmentation/Layout4Card/run目录之下。
CLS_ID_NAME_MAP = {
    0: 'student_id',
    1: 'subjective_problem',
    2: 'fillin_problem',
    3: 'objective_problem'
}

model = YOLO(model='./runs/detect/train3/weights/best.pt')
folder = './testdata'
file_names = os.listdir(folder)

random.shuffle(file_names)

imgs = []
for file_name in file_names[:10]:
    img_path = os.path.join(folder, file_name)
    img = cv2.imread(img_path)
    imgs += [img]
results =  model.predict(source=imgs, save=True, imgsz=640)

4.3 样例

cd .\segmentation\Layout4Card\
python .\infer.py

image-20230422110046357

保存的图片如下::

<img src="README.assets/image-20230422110135175.png" alt="image-20230422110135175" style="zoom: 33%;" />

5 作答区域分割-小题分割

5.1 工具

opencv-python 4.5.5.62

5.2 具体实现

(1) 图片预处理

将输入的填空题图片处理成二值图片

Debug

(2) 保留水平线

对二值图片进行腐蚀处理,保留图片中的水平线,其余不相关的笔迹 Debug

(3) 消除干扰的水平线

对所有水平线的位置进行排序,排序法则为垂直方向降序,水平方向升序。根据上图排序结果如下: .1

遍历所有定位,获取当前的水平线(在此水平线被视为宽度小于长度的矩形,每条边的存储形式为[x,y,w,h])的位置(x, y),并标记当前的y坐标,给定hmin与hmax,设置高度范围限制(y - hmax,y - hmin),记录处于该范围的定位,若遇见范围外的,更新y坐标和高度限制。 遍历结束后将标记的目标移除,剩下的即为检测目标。

最后再进行升序排序,进行遍历。得到检测的效果如下所示: .2

5.3 使用说明

cd segmentation/blankSegmentation
python blank_segmentation.py

根据提示输入识别的文件夹路径,确定Debug模式

在Debug模式下会在debug文件夹中输出扫描结果,如样例所示: 原图 Debug

6 选择题模型

6.1 数据集

使用EMNIST数据集的letters部分,该部分只包含手写字母数据,适合作为选择题单字母模型数据集。

6.2 模型框架

6.2.1 SpinalNet模型

SpinalNet

模型参考地址:https://github.com/dipuk0506/SpinalNet

该神经网络模拟的是人体的躯体感觉系统。该神经网络的特点主要有:神经丛结构(体现在中间层),全局影响与局部输出等。

神经网络模型流向:输入层->中间层->输出层

中间子层接收输入的方向有输入层和前一个中间子层的输入。

6.2.2 WaveMix模型

WaveMix

模型参考地址:https://github.com/pranavphoenix/WaveMix

WaveMix模型主要利用2D离散小波变换(DWT)对空间特征进行混合,无需展开图像与自我注意力机制,利用自身图像的2D结构来提高泛化能力。

6.3 模型实现

6.3.1 SpinalNet模型

输入层先将输入的数据传入卷积层提取特征,提取的特征分成几个部分,传入不同的中间层,最后将特征合并,经过线性层输入分类结果。

6.3.2 WaveMix模型

图像首先经过卷积层,再进入一系列WaveMix块(WaveMix块里主要做离散小波变换,再按序传到具有GELU的MLP层、转置卷积层与BatchNorm层),之后进入MLP Head,再通过全局平均池化层得到分类输出层。

6.4 模型训练

模型训练地址:https://github.com/YouHui1/Character_Recognition

python train.py -k number

number == 1 时选择SpinalNet模型, number == 2 时选择WaveMix模型

训练前可在config.py里修改模型类型,训练轮数,学习率,batchsize等等。

训练完毕后,训练日志存储在log文件夹中,模型参数存储在param文件夹中

6.4 模型使用说明

将训练后的模型参数保存在某一路径中(本项目保存在CharacterRecognition文件夹中)

运行singleCharacterRecognition.py文件,根据提示输入识别单字母图片的文件夹路径,输出为字母识别结果

7 填空题模型-中英文识别

中英文识别部分,我们使用PaddlePaddleOCR+Clip来实现识别+评判的中英文填空题批改。

7.1 PaddlePaddleOCR

PaddlePaddleOCR是一个基于PaddlePaddle深度学习框架的免费、开源的OCR(Optical Character Recognition,光学字符识别)项目。它由百度开源并持续维护。PaddlePaddleOCR旨在提供一个易于使用、高性能、多语言支持的OCR解决方案。

该项目结合了最新的深度学习技术和实际应用需求,致力于为开发者提供一个简单易用、功能强大的OCR工具库。其支持的场景包括但不限于印刷体、手写体、场景文本的识别等。

7.1.1 选择PPOCR的原因

PaddlePaddleOCR在许多OCR竞赛中取得了优异的成绩,表现出了良好的泛化能力和性能。它被广泛应用于包括智能办公、金融、医疗、教育等多个领域。

PaddlePaddleOCR具有以下主要功能与特性:

  1. 多任务支持:PaddlePaddleOCR支持多种OCR任务,包括文本检测、方向分类、文本识别等,可灵活应对各种场景。
  2. 多语言支持:项目支持多种语言的识别,包括英文、中文、法文、德文、日文等,适用于国际化场景。
  3. 易于使用:PaddlePaddleOCR提供了丰富的API接口和预训练模型,开发者可以快速上手并实现自定义需求。
  4. 高性能:项目结合了最新的深度学习技术,包括卷积神经网络(CNN)和长短时记忆网络(LSTM),确保了较高的识别准确率和性能。
  5. 实时性:PaddlePaddleOCR在保证识别准确率的同时,关注实时性,可以满足实时场景下的OCR需求。

通过这些功能与特性,PaddlePaddleOCR为开发者提供了一个高效、易用、可扩展的OCR解决方案,是我们调研之后,对中文手写字体识别最好的一个开源项目

7.1.2 PPOCR的基本结构

PaddlePaddleOCR的项目架构主要包括以下几个部分:

  1. 文本检测:文本检测模块负责在图像中定位文本区域。PaddlePaddleOCR提供了多种检测算法,如DB(Differentiable Binarization)、EAST(Efficient and Accurate Scene Text Detector)等,以满足不同场景下的检测需求。
  2. 方向分类:方向分类模块用于判断检测到的文本区域的方向,主要针对旋转文本进行处理。这有助于将文本区域校正到统一方向,为后续的文本识别做好准备。
  3. 文本识别:文本识别模块负责从校正后的文本区域中提取文本信息。PaddlePaddleOCR采用了CRNN(Convolutional Recurrent Neural Network)等先进算法进行文本识别,以实现高准确率的字符识别。
  4. 模型训练与优化:PaddlePaddleOCR提供了丰富的预训练模型和训练脚本,支持用户根据自己的数据集进行模型训练。此外,项目还提供了模型优化工具,帮助用户在保持准确率的同时,降低模型复杂度,提高推理速度。
  5. 推理部署:PaddlePaddleOCR支持多种部署方式,包括Python API、C++ API和服务端部署。项目提供了易用的部署工具和教程,使得OCR功能能够方便地集成到各种应用中。
  6. 工具与API:PaddlePaddleOCR提供了多种工具和API,帮助用户快速上手项目并实现自定义功能。例如,项目提供了可视化工具,方便用户对检测与识别结果进行分析。

这个架构确保了PaddlePaddleOCR可以适应不同场景的文本识别需求,同时易于开发者使用和定制。

img

7.1.3 预训练模型

PaddlePaddleOC

Related Skills

View on GitHub
GitHub Stars441
CategoryDevelopment
Updated3d ago
Forks122

Languages

Python

Security Score

95/100

Audited on Mar 30, 2026

No findings