数据转换模版
import os
import json
from collections import Counter
import random
import shutil
from pathlib import Path
import yaml
def count_labels(json_dir):
counter = Counter()
for filename in os.listdir(json_dir):
if filename.endswith(".json"):
path = os.path.join(json_dir, filename)
data = json.load(open(path, encoding="utf-8"))
for shape in data["shapes"]:
counter[shape["label"]] += 1
print(counter)
names = list(counter.keys())
return list(names)
---------- 1. JSON 转 YOLO TXT ----------
def json2yolo(json_dir, txt_dir, class_names):
json_dir = Path(json_dir)
txt_dir = Path(txt_dir)
txt_dir.mkdir(exist_ok=True)
class_to_id = {name: i for i, name in enumerate(class_names)}
for jf in json_dir.glob("*.json"):
data = json.load(open(jf, encoding="utf-8"))
w, h = data["imageWidth"], data["imageHeight"]
lines = []
for shape in data["shapes"]:
label = shape["label"]
points = shape["points"]
xs = [p[0] for p in points]
ys = [p[1] for p in points]
xmin, xmax = min(xs), max(xs)
ymin, ymax = min(ys), max(ys)
xc = (xmin + xmax) / 2 / w
yc = (ymin + ymax) / 2 / h
bw = (xmax - xmin) / w
bh = (ymax - ymin) / h
lines.append(f"{class_to_id[label]} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}")
(txt_dir / (jf.stem + ".txt")).write_text("\n".join(lines), encoding="utf-8")
print("JSON 转换完成,TXT 目录:", txt_dir)
---------- 2. 划分训练集 / 验证集 ----------
def split_dataset(img_dir, txt_dir, out_dir, train_ratio=0.8):
img_dir, txt_dir, out_dir = Path(img_dir), Path(txt_dir), Path(out_dir)
for sub in ["images/train", "images/val", "labels/train", "labels/val"]:
(out_dir / sub).mkdir(parents=True, exist_ok=True)
找出有对应 txt 的图片
pairs = []
for img in img_dir.glob("*"):
txt = txt_dir / (img.stem + ".txt")
if img.suffix.lower() in [".jpg", ".jpeg", ".png", ".bmp"] and txt.exists():
pairs.append((img, txt))
random.seed(42)
random.shuffle(pairs)
n = int(len(pairs) * train_ratio)
train, val = pairs[:n], pairs[n:]
for split, items in [("train", train), ("val", val)]:
for img, txt in items:
shutil.copy(img, out_dir / "images" / split / img.name)
shutil.copy(txt, out_dir / "labels" / split / txt.name)
print(f"划分完成:train={len(train)}, val={len(val)}")
---------- 3. 生成 data.yaml ----------
def make_yaml(out_dir, class_names):
data = {
"path": str(Path(out_dir).resolve()),
"train": "images/train",
"val": "images/val",
"names": {i: name for i, name in enumerate(class_names)},
}
yaml.safe_dump(data, open(Path(out_dir) / "data.yaml", "w", encoding="utf-8"),
allow_unicode=True, sort_keys=False)
print("data.yaml 已生成")
if name == "main":
# 图片和json文件在同一个文件夹中
img_dir = r"E:\20260914_yolov8\images\imgs0_augmented"
# 统计类别标注数量和标注的名称
# class_names = count_labels(img_dir)
# print(class_names )
class_names = ['person', 'operatingbar', 'wrongglove', 'badge', 'grove']
txt_dir = r"E:\20260914_yolov8\images\imgs0_augmented\labels"
out_dir = r"E:\20260914_yolov8\images\imgs0_augmented\dataset"
1. JSON 转 YOLO TXT
json2yolo(img_dir, txt_dir, class_names)
# 2. 划分训练集 / 验证集
split_dataset(img_dir, txt_dir, out_dir, train_ratio=0.8)
# 3. 生成 data.yaml
make_yaml(out_dir, class_names)
方法二:
使用
labelme2yolo --json_dir imgs --val_size 0.2 --test_size 0

浙公网安备 33010602011771号