目录
一 数据集制作
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