Files
HSAP/datasets/dms/scripts/test_export_ls_to_yolo.py
Chengfang Lu e72bc061c5 feat: HSAP platform v2 — modular navigation, quality review, audit log, world model simulation
Major changes:
- New frontend (platform/web/): Vite + React 18 + TypeScript + Tailwind
- 4-module navigation: 数据送标 / 模型管理 / 车队管理 / 系统管理
- Data catalog with charts (DMS/ADAS/Lane 3-tab view)
- Quality review workflow (标注质检): Good/Fine/Bad scoring with auto-advance
- Audit enhancements: batch operations, rejection categories, Feishu notifications
- Operation audit log (操作日志)
- World model simulation studio (仿真工坊)
- Dataset version management with snapshots and diff
- ADAS 7-class dataset integration (138K images organized + compressed)
- User management with Feishu integration and pagination
- CRUD/search/filter on all pages, card layout redesign
- PIL-optimized image overlay rendering
- Auto-snapshot on build, in_review workflow stage
- Removed embedded algorithm code (now in workspace)
2026-06-03 11:40:21 +08:00

144 lines
4.0 KiB
Python

#!/usr/bin/env python3
"""export_ls_to_yolo 单元测试(无 pytest 依赖)。"""
from __future__ import annotations
import hashlib
import json
import sys
import tempfile
from pathlib import Path
SCRIPT_DIR = Path(__file__).resolve().parent
sys.path.insert(0, str(SCRIPT_DIR))
from export_ls_to_yolo import ( # noqa: E402
convert_regions_to_yolo_lines,
export_batch,
)
from ingest_incremental import validate_detect_label, validate_pose_label # noqa: E402
def _task_id(rel: str) -> str:
return hashlib.sha256(rel.encode()).hexdigest()[:16]
def test_detect_conversion() -> None:
regions = [
{
"type": "rectanglelabels",
"value": {
"x": 10.0,
"y": 20.0,
"width": 30.0,
"height": 40.0,
"rectanglelabels": ["face"],
},
}
]
lines = convert_regions_to_yolo_lines(
regions,
mode="detect",
class_map={"face": 0, "eye_open": 1},
)
assert len(lines) == 1
parts = lines[0].split()
assert len(parts) == 5
assert parts[0] == "0"
assert abs(float(parts[1]) - 0.25) < 1e-5 # cx = (10+15)/100
assert abs(float(parts[2]) - 0.40) < 1e-5 # cy = (20+20)/100
err = validate_detect_label("\n".join(lines), 4)
assert err is None, err
def test_pose_conversion() -> None:
regions = [
{
"type": "rectanglelabels",
"value": {
"x": 10.0,
"y": 20.0,
"width": 30.0,
"height": 40.0,
"rectanglelabels": ["face"],
},
},
{
"type": "keypointlabels",
"value": {"x": 35.6, "y": 52.9, "width": 0.5, "keypointlabels": ["kp_01"]},
},
{
"type": "keypointlabels",
"value": {"x": 50.0, "y": 50.0, "width": 0.5, "keypointlabels": ["kp_10"]},
},
]
kpt_map = {f"kp_{i:02d}": i for i in range(37)}
lines = convert_regions_to_yolo_lines(
regions,
mode="pose",
class_map={"face": 0},
kpt_map=kpt_map,
kpt_shape=[37, 3],
)
assert len(lines) == 1
parts = lines[0].split()
assert len(parts) == 116
assert parts[0] == "0"
# kp_01 at index 1 -> fields 5+3..5+5
assert abs(float(parts[8]) - 0.356) < 1e-3
assert abs(float(parts[9]) - 0.529) < 1e-3
assert parts[10] == "2.000000"
err = validate_pose_label("\n".join(lines), [37, 3])
assert err is None, err
def test_export_batch_end_to_end() -> None:
with tempfile.TemporaryDirectory() as tmp:
batch = Path(tmp)
img_rel = "images/train/sample.jpg"
img_path = batch / img_rel
img_path.parent.mkdir(parents=True)
img_path.write_bytes(b"\xff\xd8\xff")
tid = _task_id(img_rel)
ann = {
"task_id": tid,
"result": [
{
"type": "rectanglelabels",
"value": {
"x": 10.0,
"y": 20.0,
"width": 30.0,
"height": 40.0,
"rectanglelabels": ["face"],
},
},
{
"type": "keypointlabels",
"value": {"x": 25.0, "y": 40.0, "width": 0.5, "keypointlabels": ["kp_00"]},
},
],
}
ann_dir = batch / "labels" / "ls_annotations"
ann_dir.mkdir(parents=True)
(ann_dir / f"{tid}.json").write_text(json.dumps(ann), encoding="utf-8")
result = export_batch(batch, "addw_face", mode="pose")
assert result["written"] == 1
out = batch / "labels" / "train" / "sample.txt"
assert out.is_file()
parts = out.read_text().strip().split()
assert len(parts) == 116
def main() -> int:
test_detect_conversion()
test_pose_conversion()
test_export_batch_end_to_end()
print("OK export_ls_to_yolo tests")
return 0
if __name__ == "__main__":
raise SystemExit(main())