- 图片统一成 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>
63 lines
1.9 KiB
Python
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
|