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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/960434.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python GUI 开发 | PySide6 辅助工具简介

关注这个框架的其他相关笔记:Python GUI 开发 | PySide6 & PyQt6 学习手册-CSDN博客 在上一章中,我们介绍了如何搭建 PySide6 & PyQt6 的开发环境。在搭建环境的时候我们配置了几个几个快捷工具,很多小伙伴可能都不知道是干啥用的。那…

头像生成小程序搭建(免费分享)

如下图为小程序页面的基本效果&#xff0c;下面将介绍该小程序的功能 页面template代码如下&#xff1a; <template><view class"avatar-containner"><block v-if"!showCropper"><image class"pageback" src"../../s…

Java面试题2025-设计模式

1.说一下开发中需要遵守的设计原则&#xff1f; 设计模式中主要有六大设计原则&#xff0c;简称为SOLID &#xff0c;是由于各个原则的首字母简称合并的来(两个L算一个,solid 稳定的)&#xff0c;六大设计原则分别如下&#xff1a; 1、单一职责原则 单一职责原则的定义描述非…

Windows Docker Desktop安装及使用 Docker 运行 MySQL

Docker Desktop是Docker的官方桌面版&#xff0c;专为Mac和Windows用户设计&#xff0c;提供了一个简单易用的界面来管理和运行Docker容器。它集成了Docker引擎&#xff0c;为开发人员提供了一个快速、可靠、可扩展的方式来构建、运行和管理应用。DockerDesktop的优势在于&…

python基础语法(4) ----- 学习笔记分享

目录 Python 使用库 以及 实战的一些案例 1. 标准库 1.1 认识标准库 1.2 使用import导入模块 1.3 代码示例:日期及结算 1.4 代码示例:字符串操作 1.5 代码示例 : 文件查找工具 2. 第三方库 2.1 认识第三方库 2.2 使用pip 2.3 代码示例:生成二维码 (1) 使用搜索引擎,…

Python-基础环境(01) 虚拟环境,Python 基础环境之虚拟环境,一篇文章助你完全搞懂!

Python的虚拟环境是一种工具&#xff0c;它能够创建一个隔离的独立Python环境。每个虚拟环境都有自己独立的Python解释器和安装的包&#xff0c;不会与其他虚拟环境或系统的全局Python环境发生冲突。虚拟环境特别适用于以下情况&#xff1a; 项目隔离&#xff1a;不同的项目可…

项目开发实践——基于SpringBoot+Vue3实现的在线考试系统(九)(完结篇)

文章目录 一、成绩查询模块实现1、学生成绩查询功能实现1.1 页面设计1.2 前端页面实现1.3 后端功能实现2、成绩分段查询功能实现2.1 页面设计2.2 前端页面实现2.3 后端功能实现二、试卷练习模块实现三、我的分数模块实现1、 页面设计2、 前端页面实现3、 后端功能实现四、交流区…

Redis --- 分布式锁的使用

我们在上篇博客高并发处理 --- 超卖问题一人一单解决方案讲述了两种锁解决业务的使用方法&#xff0c;但是这样不能让锁跨JVM也就是跨进程去使用&#xff0c;只能适用在单体项目中如下图&#xff1a; 为了解决这种场景&#xff0c;我们就需要用一个锁监视器对全部集群进行监视…

ML基础——分类模型的评估指标

以鸢尾花的分类分析为例&#xff1a; 首先我们对于3类分类做了个数字编码&#xff0c;012对应3个分类&#xff0c; 所以这就是3个分类下的预测结果指标&#xff1a; 分类为0的准确率、召回率、F1-score&#xff0c;以及support 因为前面我们数据集划分为了105 train&#xff…

安装Office自定义项,安装期间出错

个人博客地址&#xff1a;安装Office自定义项&#xff0c;安装期间出错 | 一张假钞的真实世界 卸载PowerDesigner后&#xff0c;打开“WPS文字”时出现下图错误&#xff1a; 解决方法&#xff1a; 按“WinR”快捷键&#xff0c;打开【运行】框&#xff0c;在对话框中输入“re…

Arouter详解・常见面试题

前言&#xff1a;ARouter是一个用于 Android App 进行组件化改造的路由框架 —— 支持模块间的路由、通信、解耦。 一、路由简介&#xff1a; 路由&#xff1a;就是通过互联的网络把信息从源地址传输到目的地址的活动。完成路由这个操作的实体设备就是 路由器&#xff08;Rout…

能量提升法三:赞美

前情回顾&#xff1a; 《能量提升法二&#xff1a;感恩》 片段&#xff1a;“感恩&#xff0c;就像是在跟世界说&#xff1a;谢谢你&#xff0c;我收到了&#xff0c;我很喜欢&#xff0c;请多来点” 把它归还人海&#xff0c;就当作每一个人&#xff0c;都有可能是曾经帮助…

翼星求生服务器搭建【Icarus Dedicated Server For Linux】

一、前言 本次搭建的服务器为Steam平台一款名为Icarus的沙盒、生存、建造游戏,由于官方只提供了Windows版本服务器导致很多热爱Linux的小伙伴无法释怀,众所周知Linux才是专业服务器的唯一准则。虽然Github上已经有大佬制作了容器版本但是容终究不够完美,毕竟容器无法与原生L…

Java编程语言:辉煌的历史与未来前景

如果将软件开发世界比喻成一个宇宙&#xff0c;Java 无疑是其中最亮的星星之一。它从诞生起就改变了软件开发世界的格局。发展到今天&#xff0c;Java仍然是这个世界上最重要的编程语言之一。当然&#xff0c;它也面临着新的挑战。 Java的诞生 回溯到 1991 年&#xff0c;在 …

为什么噪声不是过拟合的原因?

直观解释&#xff1a;为什么噪声不是过拟合的原因?又什么只要没有过拟合就一定有噪声?_哔哩哔哩_bilibili

【JavaWeb06】Tomcat基础入门:架构理解与基本配置指南

文章目录 &#x1f30d;一. WEB 开发❄️1. 介绍 ❄️2. BS 与 CS 开发介绍 ❄️3. JavaWeb 服务软件 &#x1f30d;二. Tomcat❄️1. Tomcat 下载和安装 ❄️2. Tomcat 启动 ❄️3. Tomcat 启动故障排除 ❄️4. Tomcat 服务中部署 WEB 应用 ❄️5. 浏览器访问 Web 服务过程详…

C语言【基础篇】之流程控制——掌握三大结构的奥秘

流程控制 &#x1f680;前言&#x1f99c;顺序结构&#x1f4af; 定义&#x1f4af;执行规则 &#x1f31f;选择结构&#x1f4af;if语句&#x1f4af;switch语句&#x1f4af;case穿透规则 &#x1f914;循环结构&#x1f4af;for循环&#x1f4af;while循环&#x1f4af;do -…

sunrays-framework配置重构

文章目录 1.common-log4j2-starter1.目录结构2.Log4j2Properties.java 新增两个属性3.Log4j2AutoConfiguration.java 条件注入LogAspect4.ApplicationEnvironmentPreparedListener.java 从Log4j2Properties.java中定义的配置读取信息 2.common-minio-starter1.MinioProperties.…

【Elasticsearch】内置分词器和IK分词器

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

简易版RAG实现

之前玩过一次RAG&#xff08;检索增强生成&#xff09;&#xff0c;链接&#xff0c;十分简陋&#xff0c;现在已经无用了&#xff0c;时隔1年半以后又再需要实现一次。其实现在做RAG已经算相对成熟了&#xff0c;要求不高的话甚至可以直接跑langchain-chatchat这类现成的。因为…