Files
HSAP/platform/as_platform/labeling/cvat_config.py
Chengfang Lu 483e027482 feat: 合并 Docker Compose、标注表格优化与部署文档
将 platform + CVAT 合并为单文件 docker-compose.yml,完善 .env 与 init/dev_up 脚本;
新增 docs/DEPLOY.md 与更新 README 以支持新机器部署;含数据湖示例、车队地图、
紧凑表格 UI、ADAS det_7cls 路径与批次台账等近期改动。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-16 17:06:31 +08:00

160 lines
5.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""CVAT 标注配置:为 DMS / ADAS / Lane 生成 label schema唯一标注引擎"""
from __future__ import annotations
from typing import Any
from as_platform.config import WORKSPACE
from as_platform.labeling.scope import labeling_profile_key, load_dms_registry, load_labeling_registry
# Lane 车道线 — 折线
LANE_LABELS: list[dict[str, Any]] = [
{
"name": "lane_line",
"type": "polyline",
"attributes": [
{
"name": "type",
"mutable": False,
"input_type": "select",
"values": ["solid", "dashed", "double_solid", "double_dashed", "solid_dashed"],
"default_value": "solid",
},
{
"name": "color",
"mutable": False,
"input_type": "select",
"values": ["white", "yellow", "blue", "other"],
"default_value": "white",
},
],
},
{
"name": "curb",
"type": "polyline",
"attributes": [
{
"name": "type",
"mutable": False,
"input_type": "select",
"values": ["high", "low", "none"],
"default_value": "low",
},
],
},
{"name": "stop_line", "type": "polyline"},
]
# ADAS cuboid_7cls — 单目图像 cuboid
ADAS_CUBOID_7CLS_LABELS: list[dict[str, Any]] = [
{"name": "car", "type": "cuboid"},
{"name": "pedestrian", "type": "cuboid"},
{"name": "truck", "type": "cuboid"},
{"name": "bus", "type": "cuboid"},
{"name": "motorcycle", "type": "cuboid"},
{"name": "tricycle", "type": "cuboid"},
{"name": "traffic cone", "type": "cuboid"},
]
def _rect_label(name: str, **attrs: Any) -> dict[str, Any]:
lb: dict[str, Any] = {"name": name, "type": "rectangle"}
if attrs:
lb["attributes"] = attrs
return lb
def _dms_registry_task_config(task: str, mode: str | None) -> dict[str, Any]:
import sys
scripts = WORKSPACE / "datasets" / "dms" / "scripts"
if str(scripts) not in sys.path:
sys.path.insert(0, str(scripts))
from task_registry import get_mode_config, resolve_task_id
reg = load_dms_registry()
task_r, mode_r = resolve_task_id(task, mode)
return get_mode_config(task_r, mode_r, reg)
def _labels_from_class_names(names: list[str] | dict[int | str, str]) -> list[dict[str, Any]]:
if isinstance(names, dict):
ordered = [names[k] for k in sorted(names, key=lambda x: int(x))]
else:
ordered = list(names)
return [_rect_label(str(n)) for n in ordered]
def _dms_pose_labels() -> list[dict[str, Any]]:
labels: list[dict[str, Any]] = [_rect_label("face")]
labels.extend({"name": f"kp_{i:02d}", "type": "points"} for i in range(37))
return labels
def _dms_labels(task: str, mode: str | None) -> list[dict[str, Any]]:
tcfg = _dms_registry_task_config(task, mode)
ttype = tcfg.get("type") or "detect"
if ttype == "pose":
return _dms_pose_labels()
names = tcfg.get("names")
if names:
return _labels_from_class_names(names)
return [_rect_label("object")]
def _labels_from_registry_profile(project: str, task: str, mode: str | None) -> list[dict[str, Any]] | None:
reg = load_dms_registry() if project == "dms" else None
pk = labeling_profile_key(project, task, mode, reg)
prof = (load_labeling_registry().get("profiles") or {}).get(pk) or {}
cvat_names = prof.get("cvat_labels")
if cvat_names:
label_type = prof.get("cvat_label_type") or (
"cuboid" if project == "adas" and task == "cuboid_7cls" else "rectangle"
)
return [{"name": str(n), "type": label_type} for n in cvat_names]
return None
def build_cvat_labels(
project: str,
task: str | None = None,
mode: str | None = None,
annotation_types: list[str] | None = None,
) -> list[dict[str, Any]]:
"""根据 HSAP project/task/mode 生成 CVAT Task 的 labels 定义。"""
task = task or ""
prof_labels = _labels_from_registry_profile(project, task, mode)
if prof_labels is not None:
return prof_labels
if project == "adas":
if task == "cuboid_7cls":
return ADAS_CUBOID_7CLS_LABELS
if task == "det_7cls":
return [_rect_label(n) for n in [
"pedestrian", "car", "truck", "bus", "motorcycle", "tricycle", "traffic cone",
]]
return ADAS_CUBOID_7CLS_LABELS
if project == "lane":
return LANE_LABELS
if project == "dms":
return _dms_labels(task, mode)
return [_rect_label("object")]
def resolve_annotation_types(project: str, task: str | None = None, mode: str | None = None) -> list[str]:
mapping = {
"dms": ["bbox", "keypoint"],
"adas": ["cuboid"],
"lane": ["polyline"],
}
if project == "adas" and task == "cuboid_7cls":
return ["cuboid"]
if project == "adas" and task == "det_7cls":
return ["bbox"]
if project == "dms" and task == "adas":
return ["bbox"]
return mapping.get(project, ["bbox"])