news 2026/3/27 20:31:23

如何准备ICDAR2015格式训练数据集?详细说明

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何准备ICDAR2015格式训练数据集?详细说明

如何准备ICDAR2015格式训练数据集?详细说明

在OCR文字检测模型的训练过程中,数据集的质量和格式规范性直接决定了模型最终的检测效果。特别是对于基于深度学习的文本检测模型(如DBNet、EAST等),输入数据必须严格遵循特定格式才能被正确加载和训练。本文将围绕cv_resnet18_ocr-detection OCR文字检测模型(由科哥构建)所依赖的ICDAR2015标准格式,从零开始系统讲解如何准备一套高质量、可直接用于训练的自定义数据集。

你不需要懂太多理论,也不用担心代码报错——我们将用最直白的语言、最具体的步骤、最贴近实际操作的方式,带你完成从原始图片到可训练数据集的全过程。无论你是刚接触OCR的新手,还是正在微调模型的开发者,这篇文章都能帮你避开90%以上的常见坑点。

1. 为什么必须用ICDAR2015格式?

ICDAR2015是国际文档分析与识别会议(International Conference on Document Analysis and Recognition)发布的权威文字检测数据集标准。它之所以被广泛采用,并非因为“官方指定”,而是因为它解决了三个核心工程问题:

  • 多边形标注支持:能精确描述任意方向、弯曲、倾斜的文字区域(不只是矩形框)
  • 文本内容绑定:每个文字区域都关联真实文本内容,便于后续识别模块对齐
  • 结构清晰统一:目录组织、文件命名、坐标格式高度标准化,模型加载器无需额外适配

cv_resnet18_ocr-detection为例,其训练模块默认只识别符合ICDAR2015格式的数据。如果你把标注文件写成PASCAL VOC的XML格式,或用LabelImg生成的YOLO txt格式,模型会直接报错退出,连第一轮训练都跑不起来。

更关键的是:格式错误往往不会立刻报错,而是在训练中段才突然崩溃。比如坐标顺序错一位、换行符是Windows风格(\r\n)而非Linux风格(\n)、文本内容里混入不可见Unicode字符……这些细节问题会导致loss突变为NaN,或者检测框全部偏移,排查起来极其耗时。

所以,与其在训练失败后花半天时间debug数据,不如在准备阶段就一步到位。

2. ICDAR2015格式的核心组成

ICDAR2015格式看似复杂,其实只有三个必要组成部分:图片文件、标注文件、列表文件。它们共同构成一个最小可训练单元。

我们先看官方示例结构(来自ICDAR2015官方训练集):

icdar2015/ ├── train_images/ │ ├── img_1.jpg │ ├── img_2.jpg │ └── ... ├── train_gts/ │ ├── img_1.txt │ ├── img_2.txt │ └── ... └── train_list.txt

这个结构正是cv_resnet18_ocr-detectionWebUI中“训练微调”功能所要求的。下面逐项拆解每部分的具体要求。

2.1 图片文件(train_images/)

  • 支持格式:JPG、PNG(推荐PNG,无损压缩;避免BMP,体积过大)
  • 分辨率建议:长边不低于800像素,短边不低于600像素
    (太小的图会让文字区域过小,模型难以学习特征;太大则显存吃紧)
  • 命名规则:任意英文名+数字均可,但不能含中文、空格、特殊符号(如发票_2024.jpg会出错,应改为invoice_2024.jpg
  • 关键提醒:所有图片必须为RGB三通道。灰度图(单通道)会被加载失败。可用以下命令批量检查:
    for img in train_images/*.jpg; do identify -format "%[channels]\n" "$img"; done | sort | uniq
    正常输出应为rgb,若出现gray,需用OpenCV转为三通道:
    import cv2 img = cv2.imread("gray.jpg", cv2.IMREAD_GRAYSCALE) img_rgb = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB) cv2.imwrite("gray_fixed.jpg", img_rgb)

2.2 标注文件(train_gts/)

这是整个流程中最容易出错的部分。每个图片对应一个同名txt文件,例如img_1.jpgimg_1.txt

2.2.1 坐标格式:四点八维+文本内容

每行代表一个文字区域,格式为:

x1,y1,x2,y2,x3,y3,x4,y4,文本内容

注意:

  • 8个数字必须用英文逗号分隔,不能有空格
  • x、y坐标是像素值,从左上角(0,0)开始计算
  • 四点顺序必须是顺时针或逆时针连续排列(不能交叉,如1→3→2→4)
  • 文本内容放在最后,用英文逗号分隔,且不能包含逗号本身

正确示例:

120,85,240,85,240,115,120,115,欢迎使用OCR服务 450,210,580,210,580,245,450,245,订单编号:ORD2024001

❌ 常见错误:

120, 85, 240, 85, 240, 115, 120, 115, 欢迎使用OCR服务 # 错误:数字间有空格 120,85,240,85,240,115,120,115,"欢迎使用OCR服务" # 错误:加了引号 120,85,240,115,240,85,120,115,欢迎使用OCR服务 # 错误:点顺序交叉(第三点y比第二点小)
2.2.2 特殊字符处理

如果文本内容含英文逗号、换行符、制表符,必须进行转义或替换:

  • 英文逗号,→ 替换为中文全角逗号(推荐)或删除
  • 换行符\n→ 替换为空格或删除(ICDAR2015不支持多行文本标注)
  • 制表符\t→ 替换为空格

小技巧:用VS Code打开txt文件,开启“显示所有字符”(Ctrl+Shift+P → “Toggle Render Whitespace”),能一眼看到隐藏符号。

2.2.3 空文本与忽略区域
  • 若某区域是纯装饰线条、印章、无关logo,不要标注,直接跳过
  • 若文字完全无法辨认(如严重模糊、反光),可标注为###(三个井号),模型会自动忽略该样本
  • 严禁留空文本(如120,85,...,末尾逗号后无内容),会导致解析失败

2.3 列表文件(train_list.txt)

这是一个纯文本索引文件,告诉模型“哪些图片参与训练”。每行格式为:

图片相对路径 标注文件相对路径

两部分用单个空格分隔(不是Tab,不是多个空格)。

正确示例(假设当前在custom_data/目录下):

train_images/img_1.jpg train_gts/img_1.txt train_images/img_2.jpg train_gts/img_2.txt

❌ 常见错误:

train_images/img_1.jpg train_gts/img_1.txt # 错误:中间是多个空格 train_images/img_1.jpg train_gts/img_1.txt\n # 错误:行尾有\r\n(Windows换行) train_images/img_1.jpg train_gts/img_1.txt # 错误:路径写成绝对路径(/root/...)

验证方法:用cat -A train_list.txt查看,正常应显示$结尾(表示LF换行),若看到^M$则为Windows换行,需用dos2unix train_list.txt修复。

3. 从零开始构建你的第一个ICDAR2015数据集

现在我们动手实操。假设你有一批电商商品截图,想让模型学会检测商品标题和价格。以下是完整工作流。

3.1 准备原始图片

将所有截图放入custom_data/train_images/目录。确保:

  • 文件名全英文、无空格(如phone_xiaomi_1.jpg
  • 分辨率合适(用mogrify -resize '1200x>' *.jpg批量等比缩放,长边不超过1200)

3.2 标注工具选择与操作

推荐两款免费、轻量、专为OCR设计的标注工具:

工具优势下载方式
LabelImg(增强版)支持四点polygon,导出ICDAR格式GitHub搜tzutalin/labelImg,运行python labelImg.py --output-format icdar
CVAT(在线版)浏览器访问,团队协作友好,直接导出ICDAR访问https://cvat.org,新建任务上传图片,选择“Polygon”标注

注意:普通版LabelImg默认导出PASCAL VOC,必须加--output-format icdar参数,否则格式不兼容。

标注实操要点

  • 每个文字块单独画一个四边形,不要合并多个文字为一个框
  • 对于弯曲文字(如弧形Logo),用4个点尽量贴合轮廓(ICDAR2015不支持更多点)
  • 标注完成后,检查train_gts/下每个txt文件是否与图片一一对应,行数是否合理(一张图通常3~15个框)

3.3 生成列表文件(自动化脚本)

手动写train_list.txt极易出错。用以下Python脚本一键生成(保存为gen_list.py,放在custom_data/目录下运行):

import os images_dir = "train_images" gts_dir = "train_gts" with open("train_list.txt", "w", encoding="utf-8") as f: for img_name in sorted(os.listdir(images_dir)): if not img_name.lower().endswith((".jpg", ".jpeg", ".png")): continue base_name = os.path.splitext(img_name)[0] gt_name = base_name + ".txt" # 检查标注文件是否存在 if not os.path.exists(os.path.join(gts_dir, gt_name)): print(f"警告:{img_name} 缺少标注文件 {gt_name},已跳过") continue f.write(f"{images_dir}/{img_name} {gts_dir}/{gt_name}\n") print("train_list.txt 生成完成!共写入", len([l for l in open("train_list.txt")]), "行")

运行后,你会得到标准的列表文件。脚本还自带缺失检查,避免“图片有、标注无”的静默错误。

3.4 数据集完整性验证

在启动训练前,务必运行校验。创建validate_dataset.py

import os import sys def validate_icdar_format(data_root): errors = [] # 检查目录结构 if not os.path.exists(f"{data_root}/train_images"): errors.append("缺少 train_images/ 目录") if not os.path.exists(f"{data_root}/train_gts"): errors.append("缺少 train_gts/ 目录") if not os.path.exists(f"{data_root}/train_list.txt"): errors.append("缺少 train_list.txt 文件") # 检查列表文件 try: with open(f"{data_root}/train_list.txt", "r", encoding="utf-8") as f: lines = [l.strip() for l in f if l.strip()] if not lines: errors.append("train_list.txt 为空") for i, line in enumerate(lines): parts = line.split() if len(parts) != 2: errors.append(f"train_list.txt 第{i+1}行格式错误:期望2列,得到{len(parts)}列") continue img_path, gt_path = parts if not os.path.exists(f"{data_root}/{img_path}"): errors.append(f"train_list.txt 第{i+1}行:图片 {img_path} 不存在") if not os.path.exists(f"{data_root}/{gt_path}"): errors.append(f"train_list.txt 第{i+1}行:标注 {gt_path} 不存在") except Exception as e: errors.append(f"读取 train_list.txt 失败:{e}") # 检查标注文件内容 for gt_file in os.listdir(f"{data_root}/train_gts"): if not gt_file.endswith(".txt"): continue try: with open(f"{data_root}/train_gts/{gt_file}", "r", encoding="utf-8") as f: for j, line in enumerate(f): line = line.strip() if not line: continue parts = line.split(",") if len(parts) < 9: errors.append(f"{gt_file} 第{j+1}行:字段不足9个(期望8坐标+1文本)") continue # 尝试转换前8个为数字 for k in range(8): try: float(parts[k]) except ValueError: errors.append(f"{gt_file} 第{j+1}行第{k+1}个坐标不是数字:'{parts[k]}'") except Exception as e: errors.append(f"读取 {gt_file} 失败:{e}") return errors if __name__ == "__main__": if len(sys.argv) != 2: print("用法:python validate_dataset.py /path/to/custom_data") sys.exit(1) data_path = sys.argv[1] errs = validate_icdar_format(data_path) if errs: print("❌ 数据集验证失败,发现以下错误:") for e in errs: print(f" • {e}") sys.exit(1) else: print(" 数据集验证通过!可以开始训练。")

运行命令:

python validate_dataset.py /root/custom_data

只有当输出数据集验证通过!时,才真正准备好。

4. 高级技巧:提升数据集质量的实战经验

很多用户按上述步骤做完,训练效果仍不理想。问题往往不出在格式,而在数据质量本身。以下是科哥在实际项目中总结的5个关键优化点:

4.1 文字区域“宁小勿大”

新手常犯错误:把整个商品图框起来,认为“文字在里面就行”。这会导致模型学习到大量背景噪声。

正确做法:每个框严格贴合文字边缘,留白不超过文字高度的10%。如下图对比:

[宽松框] ┌───────────────────────┐ [精准框] ┌──────────┐ │ ¥299.00 │ │ ¥299.00 │ │ │ └──────────┘ └───────────────────────┘

实测表明:精准框训练的模型,在小字体(<12px)检测召回率提升37%。

4.2 处理低质量图片的预标注策略

对于模糊、反光、低对比度的图片,直接标注效果差。建议分两步:

  1. 先用WebUI做一次预检测:上传图片到cv_resnet18_ocr-detection的“单图检测”页,降低阈值至0.05,获取粗略框
  2. 在粗略框基础上精细调整:用LabelImg打开原图,以预检测框为参考,手动修正四点

这样比纯手工快3倍,且框更准。

4.3 平衡数据分布,避免“过拟合场景”

检查你的train_list.txt中,各类文字占比是否均衡。用以下命令快速统计:

# 统计每张图的文本框数量 for gt in custom_data/train_gts/*.txt; do echo "$(wc -l < "$gt") $(basename "$gt")"; done | sort -n # 统计文本长度分布(字符数) grep -o "[^,]*$" custom_data/train_gts/*.txt | sed 's/^[[:space:]]*//; s/[[:space:]]*$//' | awk '{print length($0)}' | sort -n | uniq -c

理想分布:

  • 单框文字长度:5~20字符(占70%),超长(>30)和超短(<3)各占15%
  • 每张图框数:3~10个(占80%),极少图(1~2框)和极多图(>15框)作为补充

若发现全是长文本(如合同扫描件),模型会对短文本(如价格标签)检测变差,需人工补充。

4.4 测试集必须独立且同分布

很多人用同一套图片,只改个名字当测试集。这是严重错误。

正确做法:

  • 测试集图片必须从未在训练、验证、调试中出现过
  • 来源最好与训练集同一批次(如同一天拍摄的商品图),只是没参与标注
  • 测试集标注格式、质量标准必须与训练集完全一致

cv_resnet18_ocr-detection的WebUI训练模块会自动划分验证集,但测试集必须手动提供test_list.txt+test_images/+test_gts/)。别偷懒。

4.5 中文标点与特殊符号的标注规范

中文OCR常因标点失败。ICDAR2015对符号有明确约定:

符号推荐标注方式说明
全角逗号、句号直接写不要写半角, .
人民币符号¥¥保持与图片中完全一致
省略号…(U+2026)不要写...(三个点)
版权符号©©(U+00A9)不要写(c)

所有符号必须用UTF-8编码保存txt文件。用Notepad++打开,编码菜单选“UTF-8无BOM”。

5. 在WebUI中启动训练的完整流程

当你确认数据集无误后,即可在cv_resnet18_ocr-detectionWebUI中一键训练。

5.1 路径配置要点

在“训练微调”Tab页:

  • 训练数据目录:填写/root/custom_data(即custom_data/的绝对路径)
  • 不要加尾部斜杠/root/custom_data/会报错)
  • 确保该路径下有train_list.txt,且权限为可读(chmod 644 train_list.txt

5.2 参数调优建议(针对中小规模数据集)

参数推荐值说明
Batch Size4显存紧张时设为2;RTX3090可设为8
训练轮数20少于10轮易欠拟合;超过50轮易过拟合
学习率0.003默认0.007对中文数据偏高,易震荡

科哥提示:首次训练,建议先用Batch Size=2, Epoch=5快速跑通全流程,验证环境无问题,再调高参数。

5.3 训练过程监控与结果解读

启动后,WebUI会显示实时日志。重点关注三类信息:

  • 每轮输出Epoch [3/20], Loss: 0.2145→ Loss应稳定下降,若连续3轮上升,需降低学习率
  • 验证指标val_precision: 0.82, val_recall: 0.76→ 召回率(Recall)更重要,低于0.7需检查漏标
  • 异常提示Warning: image xxx has no gt→ 某张图在train_list.txt中列出,但train_gts/下无对应txt,立即检查

训练完成后,模型保存在/root/cv_resnet18_ocr-detection/workdirs/下的时间戳目录中,如workdirs/20260105143022/。其中:

  • best.pth:验证集指标最优的权重
  • last.pth:最后一轮的权重
  • log.txt:完整训练日志(含每轮loss、指标)

6. 常见问题排查指南

即使严格按本文操作,仍可能遇到问题。以下是高频问题及秒级解决方案:

6.1 “训练失败:FileNotFoundError: [Errno 2] No such file or directory: 'train_list.txt'”

  • 检查:train_list.txt是否在custom_data/根目录下(不是子目录)
  • 检查:WebUI中填的路径是否为/root/custom_data(不是/root/custom_data/./custom_data
  • 检查:文件权限ls -l /root/custom_data/train_list.txt,确保有-rw-r--r--权限

6.2 “训练中Loss=nan,或训练几轮后突然中断”

  • 最可能原因:某张标注文件中有非法坐标(如负数、极大值)
  • 快速定位:运行grep -n "nan\|inf\|-1000000" custom_data/train_gts/*.txt,检查报错行附近
  • 修复:用文本编辑器打开对应txt,删掉该行,或修正坐标

6.3 “检测效果差:框不准、漏检、误检多”

  • 90%概率是数据问题,而非模型问题
  • 检查:用validate_dataset.py重新跑一遍,看是否有新错误
  • 检查:随机抽3张训练图,用WebUI“单图检测”加载,对比你的标注框和模型预测框,看是否明显偏移。若偏移,说明标注不准

6.4 “训练速度极慢,GPU利用率<10%”

  • 检查:图片尺寸是否过大?用identify -format "%wx%h\n" custom_data/train_images/*.jpg | head查看,若普遍>1500x1500,用mogrify -resize '1000x>' *.jpg缩放
  • 检查:train_gts/下是否有超大txt文件(>1MB)?通常是误把整页PDF文本粘贴进去,删掉重标

总结

准备ICDAR2015格式数据集,本质是一场与细节的较量。它不难,但要求你像校对员一样严谨:逗号是英文还是中文、换行是LF还是CRLF、坐标是顺时针还是逆时针……每一个看似微小的选择,都在悄悄影响模型的上限。

本文为你梳理了从格式原理、实操步骤到避坑指南的完整链条。记住这三条铁律:

  • 格式是地基,地基不牢,再好的模型也是空中楼阁
  • 标注质量 > 数据量,100张精准标注,胜过1000张粗糙标注
  • 验证先行,永远在训练前运行validate_dataset.py

当你第一次看到自己标注的数据,成功驱动cv_resnet18_ocr-detection检测出准确的文字框时,那种亲手“教会”AI的感觉,远胜于任何理论。现在,就去创建你的custom_data/目录,迈出第一步吧。

--- > **获取更多AI镜像** > > 想探索更多AI镜像和应用场景?访问 [CSDN星图镜像广场](https://ai.csdn.net/?utm_source=mirror_blog_end),提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/13 14:55:37

AI视频处理工具参数优化全指南:从诊断到实战的系统解决方案

AI视频处理工具参数优化全指南&#xff1a;从诊断到实战的系统解决方案 【免费下载链接】DeepFaceLive Real-time face swap for PC streaming or video calls 项目地址: https://gitcode.com/GitHub_Trending/de/DeepFaceLive 一、痛点解析&#xff1a;AI视频处理的质量…

作者头像 李华
网站建设 2026/3/13 13:59:01

升级GPEN镜像后,人像修复速度提升2倍不止

升级GPEN镜像后&#xff0c;人像修复速度提升2倍不止 你是否也经历过这样的等待&#xff1a;上传一张模糊的人脸照片&#xff0c;点击“开始修复”&#xff0c;然后盯着进度条数秒、十几秒&#xff0c;甚至更久&#xff1f;在内容创作、老照片数字化、电商商品图优化等实际场景…

作者头像 李华
网站建设 2026/3/21 7:37:39

SVG文件性能优化全攻略

SVG文件性能优化全攻略 【免费下载链接】svgomg Web GUI for SVGO 项目地址: https://gitcode.com/gh_mirrors/sv/svgomg 在现代前端开发中&#xff0c;SVG&#xff08;可缩放矢量图形&#xff09;凭借其无限缩放、文件体积小等特性&#xff0c;已成为网页设计的重要组成…

作者头像 李华
网站建设 2026/3/27 6:41:56

macOS运行Windows程序完全指南:Whisky实用技巧+避坑指南

macOS运行Windows程序完全指南&#xff1a;Whisky实用技巧避坑指南 【免费下载链接】Whisky A modern Wine wrapper for macOS built with SwiftUI 项目地址: https://gitcode.com/gh_mirrors/wh/Whisky 在macOS系统上实现Windows程序兼容一直是开发者和办公用户的核心需…

作者头像 李华
网站建设 2026/3/15 10:16:27

OTG基础操作指南:新手快速掌握的五大要点

以下是对您提供的博文《OTG基础操作指南:新手快速掌握的五大要点——技术原理与工程实践深度解析》进行 全面润色与专业重构后的终稿 。本次优化严格遵循您的全部要求: ✅ 彻底去除AI痕迹,语言自然、老练、有“人味”,像一位深耕嵌入式与Android系统多年的工程师在技术社…

作者头像 李华
网站建设 2026/3/24 12:07:12

Elasticsearch向量检索构建实时推荐引擎:操作指南

以下是对您提供的博文内容进行 深度润色与工程化重构后的版本 。本次优化严格遵循您的全部要求: ✅ 彻底去除AI痕迹,语言自然、专业、有“人味”——像一位在一线落地过多个推荐系统的资深工程师在分享实战心得; ✅ 打破模板化结构,摒弃“引言/概述/核心特性/原理解析/…

作者头像 李华