ICDAR2015格式怎么准备?训练数据规范详解
在OCR文字检测模型的训练过程中,数据格式是决定训练能否成功的第一道门槛。很多用户反馈“明明数据都放好了,但训练就是报错”“标注文件明明有内容,却提示找不到文本框”,这些问题90%以上都源于ICDAR2015格式理解偏差或细节疏漏。本文不讲理论、不堆参数,只聚焦一个目标:手把手带你把训练数据准备好,确保第一次训练就能跑通。
你用的是cv_resnet18_ocr-detection这个镜像——它由科哥构建,WebUI界面友好,但背后对训练数据的要求非常明确:必须严格遵循ICDAR2015标准格式。下面所有内容,都来自真实踩坑经验+镜像源码验证,每一步都可直接复现。
1. 为什么必须是ICDAR2015格式?
先说结论:不是“推荐”,而是硬性要求。这个镜像的训练模块(即WebUI中“训练微调”Tab页)底层加载逻辑直接调用PaddleOCR风格的数据读取器,而该读取器默认只识别ICDAR2015结构。它不支持LabelImg的XML、COCO的JSON,也不兼容自定义CSV——强行改名或简单转换,大概率在train_gts/1.txt解析阶段就报ValueError: not enough values to unpack。
你可以把它理解成一种“语言协议”:模型是母语者,你提供的数据必须说它的母语,否则沟通失败。
正确姿势:按ICDAR2015原始结构组织,连空格、换行、标点都不能错
❌ 常见错误:用Excel另存为TXT、手动拼接坐标、中文逗号分隔、末尾多空行、坐标含小数点
2. ICDAR2015格式的完整结构解析
镜像文档里给出的目录结构是准确的,但仅看树状图容易忽略关键细节。我们拆解成三部分:目录骨架、图片命名规则、标注文件语法。
2.1 目录结构:4个核心目录 + 2个列表文件
custom_data/ ├── train_list.txt # 必须存在,且路径必须绝对正确 ├── train_images/ # 存放所有训练图片(JPG/PNG) │ ├── 1.jpg # 文件名可任意,但不能含空格/中文/特殊符号 │ └── 2.png ├── train_gts/ # 存放所有训练标注(纯TXT,无BOM,UTF-8编码) │ ├── 1.txt # 文件名必须与图片名完全一致(不含扩展名) │ └── 2.txt ├── test_list.txt # 测试集列表,格式同train_list.txt ├── test_images/ # 测试图片目录 │ └── 3.jpg └── test_gts/ # 测试标注目录 └── 3.txt致命细节提醒:
train_list.txt和test_list.txt中的路径必须是相对路径,且以train_images/或test_images/开头;train_gts/1.txt必须与train_images/1.jpg配对,哪怕你把图片叫img_001.jpg,那标注文件就必须叫img_001.txt;- 所有路径中禁止出现中文、空格、括号、&、#等字符,连下划线
_都建议少用,优先用纯数字或英文。
2.2 标注文件(.txt):一行一文本框,坐标+文本缺一不可
这是最容易出错的部分。ICDAR2015要求每个文本框占一行,格式为:
x1,y1,x2,y2,x3,y3,x4,y4,文本内容正确示例(train_gts/1.txt内容):
120,85,260,85,260,115,120,115,欢迎使用OCR服务 310,142,420,142,420,172,310,172,科哥出品❌常见错误写法:
120,85,260,85,260,115,120,115,"欢迎使用OCR服务"→ 引号非法,ICDAR2015不加引号120 85 260 85 260 115 120 115 欢迎使用OCR服务→ 空格分隔,必须用英文逗号120.5,85.2,260.1,85.3,...→ 坐标必须为整数,小数会直接报错120,85,260,85,260,115,120,115,→ 末尾多一个逗号,导致文本内容为空字符串120,85,260,85,260,115,120,115,欢迎使用OCR服务\n→ Windows换行符\r\n可能引发解析异常,务必保存为Unix换行(LF)
小白友好技巧:用VS Code打开TXT文件,右下角查看编码和换行符类型,点击切换为UTF-8+LF。
2.3 列表文件(.txt):图片路径与标注路径的“配对清单”
train_list.txt本质是一张映射表,告诉程序:“这张图对应哪个标注”。格式为:
train_images/1.jpg train_gts/1.txt train_images/2.jpg train_gts/2.txt关键规则:
- 每行两个字段,用单个空格分隔;
- 第一个字段是图片路径(相对于
custom_data/根目录); - 第二个字段是标注路径(同样相对于
custom_data/根目录); - 路径中不能有空格,也不能有中文;
- 行末不能有多余空格或制表符。
❌ 错误示例:
train_images/1.jpg train_gts/1.txt # 中间多个空格 → 解析失败 train_images/订单截图.jpg train_gts/订单截图.txt # 中文路径 → 找不到文件3. 从零开始准备一份可用数据集(实操步骤)
现在,我们用一个真实场景走一遍:你想用自己的商品宣传图训练检测模型,共15张图,已人工标好文本框。
3.1 准备工作:创建标准目录
在服务器上执行(假设你的数据将放在/root/custom_data):
mkdir -p /root/custom_data/{train_images,train_gts,test_images,test_gts} touch /root/custom_data/train_list.txt touch /root/custom_data/test_list.txt3.2 图片处理:重命名 + 格式统一
你的原始图片可能是商品A.jpeg、宣传图(1).png,全部重命名为纯数字:
# 进入原始图片目录(假设在 /root/raw_imgs) cd /root/raw_imgs # 批量重命名:按时间顺序编号,转为JPG ls -t *.jpg *.jpeg *.png | awk '{print "cp \"" $0 "\" /root/custom_data/train_images/" NR ".jpg"}' | bash # 验证结果 ls /root/custom_data/train_images/ # 输出应为:1.jpg 2.jpg 3.jpg ... 15.jpg提示:如果图片太大(>4MB),建议用
convert 1.jpg -resize 1280x -quality 85 1.jpg压缩,不影响检测效果。
3.3 标注文件生成:手写 or 工具生成?
方案A:手写(适合≤50张,快速验证)
用Excel整理坐标(列:x1,y1,x2,y2,x3,y3,x4,y4,文本),然后复制到记事本,用查找替换:
- 替换所有
制表符为英文逗号, - 替换所有
换行符为英文逗号加换行, - 最后手动删掉每行末尾多余的逗号
保存为UTF-8无BOM,扩展名.txt,按图片名存入train_gts/。
方案B:用Python脚本(推荐,100%可控)
以下脚本可直接运行,输入Excel(xlsx格式),输出标准ICDAR2015 TXT:
# save as gen_icdar.py import pandas as pd import os # 读取Excel(第一行为列名:x1,y1,x2,y2,x3,y3,x4,y4,text) df = pd.read_excel("/root/raw_imgs/labels.xlsx") # 按图片名分组(假设Excel第一列是图片名,如"1.jpg") for img_name, group in df.groupby('image_name'): # 去掉扩展名,得到基础名 base_name = os.path.splitext(img_name)[0] txt_path = f"/root/custom_data/train_gts/{base_name}.txt" with open(txt_path, "w", encoding="utf-8") as f: for _, row in group.iterrows(): # 确保坐标是整数 coords = [int(row[f"x{i}"]) for i in range(1,5)] + [int(row[f"y{i}"]) for i in range(1,5)] text = str(row["text"]).strip() line = ",".join(map(str, coords)) + "," + text f.write(line + "\n") print(f" 已生成 {txt_path}") # 生成train_list.txt with open("/root/custom_data/train_list.txt", "w", encoding="utf-8") as f: for i in range(1, 16): # 15张图 f.write(f"train_images/{i}.jpg train_gts/{i}.txt\n")运行后,你的train_gts/下就有15个标准TXT,train_list.txt也自动生成。
4. 验证数据是否合格:3个必做检查
别急着点“开始训练”,先做这三步验证,省去90%的调试时间。
4.1 检查文件数量是否匹配
cd /root/custom_data echo "图片数:" $(ls train_images/*.jpg | wc -l) echo "标注数:" $(ls train_gts/*.txt | wc -l) echo "列表行数:" $(wc -l < train_list.txt)三者必须完全相等。如果不等,说明有文件没配对,训练必然失败。
4.2 检查单个标注文件语法
随便选一个train_gts/1.txt,用以下命令快速校验:
# 检查是否每行都是8个数字+1个文本(共9个字段) awk -F',' '{print NF}' /root/custom_data/train_gts/1.txt | sort -u # 正常输出应为:9 # 如果输出9和10,说明某行多了逗号;如果只有8,说明少了文本内容4.3 检查列表文件路径是否可访问
# 取第一行,测试路径是否存在 head -1 /root/custom_data/train_list.txt | awk '{print $1, $2}' | while read img gt; do echo "检查 $img:" $(ls "$img" 2>/dev/null || echo "❌ 不存在") echo "检查 $gt:" $(ls "$gt" 2>/dev/null || echo "❌ 不存在") done只要有一处显示❌ 不存在,就立即修正路径。
5. WebUI中训练微调的实操要点
当你确认数据无误后,在WebUI中操作时,注意这些镜像特有设置:
5.1 “训练数据目录”填什么?
在“训练微调”Tab页,不要填/root/custom_data/train_images,而是填整个数据集根目录:
正确填写:/root/custom_data ❌ 错误填写:/root/custom_data/train_images 或 /root/custom_data/因为镜像内部代码会自动拼接train_list.txt、train_images/等子路径,填错根目录会导致找不到列表文件。
5.2 Batch Size怎么选?
参考镜像文档的默认值(8),但需结合你的GPU显存调整:
| GPU显存 | 推荐Batch Size | 原因 |
|---|---|---|
| ≤4GB(如GTX 1050 Ti) | 2 | 防止OOM(内存溢出) |
| 6-8GB(如RTX 2060/3060) | 4-6 | 平衡速度与稳定性 |
| ≥10GB(如RTX 3090) | 8-12 | 充分利用显存 |
如果训练启动后几秒就崩溃,大概率是Batch Size过大,立刻降为2重试。
5.3 训练轮数(Epoch)设多少?
镜像默认是5轮,这对小数据集(<50张)足够:
- 1-3轮:模型刚“认识”你的字体和背景,检测框可能偏移;
- 4-5轮:定位趋于稳定,漏检/误检明显减少;
5轮:容易过拟合,尤其当你的数据多样性不足时。
建议:首次训练设为5,观察workdirs/下的日志,如果loss在第3轮后不再下降,下次可设为3。
6. 常见报错及速查解决方案
以下是用户在训练环节最常遇到的5个报错,附带一键修复命令:
| 报错信息 | 原因 | 修复命令 |
|---|---|---|
FileNotFoundError: [Errno 2] No such file or directory: 'train_list.txt' | train_list.txt不在根目录,或名字拼错 | ls /root/custom_data/train_list.txt确认存在 |
ValueError: could not convert string to float: 'xxx' | 标注文件中有中文逗号、全角字符或空格 | sed -i 's/[[:space:]]\+/,/g; s/,/,/g; s/ /,/g' /root/custom_data/train_gts/*.txt |
AssertionError: boxes should be a list of lists | 某个TXT文件末尾有多余空行 | sed -i '/^$/d' /root/custom_data/train_gts/*.txt |
OSError: image file is truncated | 某张JPG损坏 | `identify -verbose /root/custom_data/train_images/*.jpg 2>/dev/null | grep -E "(Image: |
CUDA out of memory | Batch Size过大或图片尺寸超限 | cd /root/custom_data/train_images && mogrify -resize 1024x -quality 85 *.jpg |
7. 训练完成后,如何验证模型真的学好了?
训练结束,workdirs/下会生成新模型。别急着替换原模型,先做两件事:
7.1 用单图检测功能快速验证
- 回到WebUI首页 → “单图检测”Tab;
- 上传一张未参与训练的图(比如测试集里的
test_images/3.jpg); - 设置检测阈值为0.2,点击“开始检测”;
- 观察:
- 检测框是否紧密包裹文字(不漏字、不包背景);
- 文本内容是否识别正确(即使识别不准,检测框位置也要准);
- ❌ 如果框歪了、漏了、或者框住大片空白,说明数据标注质量有问题,需回溯检查
train_gts/。
7.2 查看训练日志中的关键指标
进入workdirs/,找到最新生成的日期文件夹(如20260105143022),打开train.log:
grep -E "(loss|acc|hmean)" /root/custom_data/workdirs/20260105143022/train.log | tail -10重点关注最后一行的hmean(综合准确率):
hmean: 0.85→ 优秀(85%以上);hmean: 0.70~0.84→ 合格,可上线;hmean: <0.65→ 数据或标注有问题,需优化。
小技巧:hmean低但loss持续下降,说明模型在“死记硬背”个别样本,此时应增加数据多样性(不同角度、光照、字体)。
8. 进阶建议:让模型更鲁棒的3个实践
数据准备只是起点,真正好用的OCR检测模型,还需要这些打磨:
8.1 主动添加“困难样本”
在你的数据集中,专门加入这几类图:
- 文字极小(<10px高)的截图;
- 背景复杂(如带网格、渐变、水印)的宣传图;
- 文字扭曲(透视变形、弧形排列)的实物照片。
每类加3-5张,单独放入train_images/并标注,能显著提升泛化能力。
8.2 使用镜像内置的图像增强(无需改代码)
虽然WebUI没开放增强开关,但该镜像默认启用了PaddleOCR的增强策略(见参考博文中的IaaAugment)。你只需确保:
- 训练图片分辨率≥640×480(太小会增强失效);
- 标注坐标是精确的四边形(不是矩形),增强才能正确变形。
8.3 保存你自己的“黄金数据集”
把经过验证的优质数据(含图片、标注、列表文件)打包:
cd /root/custom_data tar -czf my_ocr_dataset_v1.tar.gz train_images/ train_gts/ train_list.txt下次训练,直接解压就能用,避免重复踩坑。
总结
ICDAR2015格式不是玄学,它是一套清晰、严格、可验证的数据协议。本文带你穿透所有模糊地带,落到每一个文件、每一行代码、每一个标点符号上。记住这三点,你就掌握了核心:
- 结构是铁律:
train_images/+train_gts/+train_list.txt三者必须同在根目录下,路径名不能含任何“不安全”字符; - 标注是灵魂:
.txt文件里,x1,y1,x2,y2,x3,y3,x4,y4,文本—— 整数、逗号、无引号、无空行,缺一不可; - 验证是保障:训练前用3条Shell命令检查数量、语法、路径,比训练失败后查日志快10倍。
现在,你的数据已经准备好。打开WebUI,填入/root/custom_data,点击“开始训练”,看着进度条推进——那一刻,你不是在跑代码,而是在亲手教会模型读懂世界。
--- > **获取更多AI镜像** > > 想探索更多AI镜像和应用场景?访问 [CSDN星图镜像广场](https://ai.csdn.net/?utm_source=mirror_blog_end),提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。