当前位置: 首页 > article >正文

Yolo11 + OCR 营业执照识别+信息抽取(预期后续改用其他ocr更简单,推理预计使用onnxruntim加速,分c++和python两种方式部署)

目录

一 数据集制作

1 labelimg的安装与使用

2 标注方式

3 数据集制作

二 模型训练 

三 使用Yolo11 + OCR 实现“营业执照”信息解析完整方案

1 cutLinesforcode.py

2 getBusinessLicenseContentPart.py

3 getPartWords.py

4 pdfTojpg.py

5 main.py


本项目可用于毕业设计参考实验营业执照分为横版竖版整体检测+识别效果如下所示:

说明:图片来源于网络,如有侵权,请联系作者删除。

系统:Ubuntu 20.04

需要的依赖:

  • pdf2image
pip install pdf2image -i https://pypi.tuna.tsinghua.edu.cn/simple
  • yolo11
pip install ultralytics -i https://pypi.tuna.tsinghua.edu.cn/simple
  • pytesseract
pip install pytesseract -i https://pypi.tuna.tsinghua.edu.cn/simple

sudo apt update
 
sudo apt install tesseract-ocr
 
# 在线安装中文字库
 
sudo apt-get install tesseract-ocr-chi-sim

一 数据集制作


使用labelimg工具进行数据标注任务。


1 labelimg的安装与使用


安装方法: pip install labelimg
使用方法如下:
cd到labellmg所在路径

python labellmg.py


标注后生成的标记文件是xml文件。


2 标注方式


本项目的目标是解析出营业执照统一社会信用代码、名称、类型、法定代表人、经营范围、注册资本、成立日期、营业期限住所等信息
标注方式如下:

 

你可以根据自己的需求去对应进行数据集的制作,类比即可。


3 数据集制作


原始数据集格式如下图所示:

  • Annotations 里面存放标签xml文件
  • JPEGImage 里面存放原始图片
  • labels 里面存放的是标签txt文件。这个文件夹里的文件是通过脚本xmI_txt.py生成的。

xmI_txt.py代码如下

import xml.etree.ElementTree as ET
import os
import random
 
# TODO 这里按照类别去修改
classes = ['code', 'specialcode', 'name', 'type', 'representative', 'range', 'registered', 'date', 'limit', 'address']
# TODO 这里按照实际XML文件夹路径去修改
xml_filepath = 'data/Annotations/'
# TODO 这里按照实际想要保存结果txt文件夹的路径去修改
labels_savepath = 'data/labels/'
abs_path = os.getcwd()
 
 
def convert(size, box):
    dw = 1. / (size[0])
    dh = 1. / (size[1])
    x = (box[0] + box[1]) / 2.0 - 1
    y = (box[2] + box[3]) / 2.0 - 1
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return x, y, w, h
 
 
def convert_annotation(image_id):
    in_file = open(xml_filepath + '%s.xml' % (image_id), encoding='UTF-8')
    out_file = open(labels_savepath + '%s.txt' % (image_id), 'w')
    tree = ET.parse(in_file)
    root = tree.getroot()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)
    for obj in root.iter('object'):
        difficult = obj.find('difficult').text
        cls = obj.find('name').text
        if cls not in classes or int(difficult) == 1:
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
             float(xmlbox.find('ymax').text))
        b1, b2, b3, b4 = b
        # 标注越界修正
        if b2 > w:
            b2 = w
        if b4 > h:
            b4 = h
        b = (b1, b2, b3, b4)
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
 
 
def run():
    total_xml = os.listdir(xml_filepath)
    num = len(total_xml)
    names = []
    for xml in total_xml:
        names.append(xml[:-4])
    for name in names:
        convert_annotation(name)
    pass
 
 
if __name__ == '__main__':
    run()
    pass

然后,根据JPEGlmage 文件夹和labels文件夹通过脚本deal_dataset.py将数据集划分为如下结构。

deal_dataset.py 代码如下:

import os
import random
import shutil
 
# 原数据集目录
root_dir = 'data/'
# 划分比例
train_ratio = 0.8
valid_ratio = 0.1
test_ratio = 0.1
 
# 设置随机种子
random.seed(42)
 
# TODo 这里按照实际数据集路径去修改
split_dir = 'data_new/'
os.makedirs(os.path.join(split_dir, 'train/images'), exist_ok=True)
os.makedirs(os.path.join(split_dir, 'train/labels'), exist_ok=True)
os.makedirs(os.path.join(split_dir, 'valid/images'), exist_ok=True)
os.makedirs(os.path.join(split_dir, 'valid/labels'), exist_ok=True)
os.makedirs(os.path.join(split_dir, 'test/images'), exist_ok=True)
os.makedirs(os.path.join(split_dir, 'test/labels'), exist_ok=True)
 
# TODo 这里按照实际数据集路径去修改
imgpath = "JPEGImage"
labelpath = "labels"
image_files = os.listdir(os.path.join(root_dir, imgpath))
image_files.sort(key=lambda x: int(x.split('.')[0]))
print(image_files)
label_files = os.listdir(os.path.join(root_dir, labelpath))
label_files.sort(key=lambda x: int(x.split('.')[0]))
print(label_files)
# 随机打乱文件列表
combined_files = list(zip(image_files, label_files))
random.shuffle(combined_files)
image_files_shuffled, label_files_shuffled = zip(*combined_files)
print(image_files_shuffled)
print(label_files_shuffled)
# 根据比例计算划分的边界索引
train_bound = int(train_ratio * len(image_files_shuffle

http://www.kler.cn/a/522174.html

相关文章:

  • 【深度学习】 UNet详解
  • 神经网络|(七)概率论基础知识-贝叶斯公式
  • 十年筑梦,再创鲸彩!庆祝和鲸科技十周年
  • Web 代理、爬行器和爬虫
  • mybatis(112/134)
  • 2218. 从栈中取出 K 个硬币的最大面值和
  • C#,入门教程(04)——Visual Studio 2022 数据编程实例:随机数与组合
  • Python3 OS模块中的文件/目录方法说明十三
  • 通过Redis命令建立锁机制
  • 字符设备驱动模版-中断
  • 5.1.4 软件工具+开发环境
  • 【Docker】Docker入门了解
  • 本地大模型编程实战(04)给文本自动打标签
  • 【Spring】Spring概述
  • 寒假1.26
  • 【深度学习】常见模型-Transformer模型
  • 基于微信小程序游泳馆管理系统 游泳馆管理系统小程序 (设计与实现)
  • 梯度下降优化算法-RMSProp
  • 【源码+文档+调试讲解】基于Spring Boot的摇滚乐鉴赏网站的设计与实现
  • Git 出现 Please use your personal access token instead of the password 解决方法
  • 发布 VectorTraits v3.1(支持 .NET 9.0,支持 原生AOT)
  • 基于微信小程序的助农扶贫系统设计与实现(LW+源码+讲解)
  • 98.1 AI量化开发:长文本AI金融智能体(Qwen-Long)对金融研报大批量处理与智能分析的实战应用
  • 高阶C语言|深入理解字符串函数和内存函数
  • 【C++高并发服务器WebServer】-10:网络编程基础概述
  • 寒假刷题Day16