Files
Shaun ZhouandClaude Opus 5 7adc5b6332 feat(detect): YOLO 数据集统一为 PNG、按类别重命名并附 classes.txt
- 图片统一成 PNG。pearlescent / blue / uv 的原始数据是 BMP,generate_boxes.py
  按原后缀链接,于是 runs/boxes_shap 里 3685 张 BMP 与 7526 张 PNG 混在一起,
  ripple 与 uneven 两类全是 BMP。按文件头(而非后缀)判断:真 PNG 照旧硬链接,
  其余无损转换,不缩放像素,归一化框坐标原样有效;CMYK 等 PNG 存不下的模式转 RGB。
  在真实数据上核对过 3685 张转换结果逐像素一致。
- 文件按 <类别>_<序号> 重新编号。类别取标签第一列,文件名不会与标签矛盾;
  序号在类内按源路径排序、与划分无关,换种子重跑名字不变。新旧名对照写入
  name_map.csv,源文件名里的正反面、位置、时间戳不丢。--keep-names 保留原名。
- 输出 classes.txt(行号即 class_id),供 LabelImg / X-AnyLabeling 复核框时使用。
- 撞名检查改为按输出文件名的小写比较:统一后缀后 a.png 与 a.bmp 会撞,
  macOS 默认文件系统也不区分大小写。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 16:45:58 +08:00

63 lines
1.9 KiB
Python

"""YOLO 数据集格式的共用定义。
工作流里只用到"写出"这一侧:scripts/generate_boxes.py 产出的
`labels/<类别>/<图名>.txt` 与 `data.yaml` 是给外部检测训练用的交换格式。
标注文件每行一个目标,坐标相对图像宽高归一化到 [0, 1],中心点格式:
```
<class_id> <cx> <cy> <w> <h>
```
"""
from __future__ import annotations
from collections.abc import Sequence
from pathlib import Path
IMAGE_SUFFIXES = (".png", ".jpg", ".jpeg", ".bmp", ".tif", ".tiff", ".webp")
def write_classes_txt(path: str | Path, classes: Sequence[str]) -> Path:
"""写 classes.txt:每行一个类别名,行号(从 0 起)即标签里的 class_id。
ultralytics 训练只读 data.yaml;这份是给 LabelImg / X-AnyLabeling 之类
标注工具用的——人工复核、修改框时它们靠它把 class_id 映射回类别名。
"""
bad = [name for name in classes if not name.strip() or "\n" in name]
if bad:
raise ValueError(f"类别名不能为空或包含换行,否则行号与 class_id 对不上: {bad!r}")
path = Path(path)
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("".join(f"{name}\n" for name in classes), encoding="utf-8")
return path
def write_data_yaml(
path: str | Path,
classes: Sequence[str],
root: str | Path = ".",
train: str = "images/train",
val: str = "images/val",
) -> Path:
"""写一个 YOLO 风格的 data.yaml,字段与 ultralytics 通用。"""
import yaml
path = Path(path)
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(
yaml.safe_dump(
{
"path": str(root),
"train": train,
"val": val,
"nc": len(classes),
"names": dict(enumerate(classes)),
},
allow_unicode=True,
sort_keys=False,
),
encoding="utf-8",
)
return path