Skip to content

API Reference

Auto-generated reference for the ue5_vehicle_synth package via mkdocstrings. Each module below lists its public classes and functions with their docstrings and type signatures.

Package root

ue5_vehicle_synth

UE5-based synthetic vehicle keypoint dataset generation pipeline

COCO Exporter

coco_exporter

Incremental COCO-format JSON exporter for the 24-pt vehicle keypoint schema.

Classes

CocoExporter
CocoExporter(output_path: Path, dataset_name: str)

Writes a COCO-format JSON file with the 24-pt vehicle keypoint schema.

Usage

exp = CocoExporter(output_path=Path("ann.json"), dataset_name="ue5-synth-phase0") exp.begin() img_id = exp.add_image(file_name="...", width=W, height=H, metadata={...}) ann_id = exp.add_annotation(image_id=img_id, bbox=(...), keypoints=[...], area=...) exp.end()

Source code in src/ue5_vehicle_synth/coco_exporter.py
30
31
32
33
34
35
36
37
def __init__(self, output_path: Path, dataset_name: str) -> None:
    self.output_path = Path(output_path)
    self.dataset_name = dataset_name
    self._images: list[dict[str, Any]] = []
    self._annotations: list[dict[str, Any]] = []
    self._next_image_id = 1
    self._next_annotation_id = 1
    self._begun = False

Postprocess

postprocess

COCO postprocessing: validation + off-screen keypoint masking.

Classes

PostprocessError

Bases: ValueError

Raised when a COCO file fails validation.

Functions:

validate_coco_file
validate_coco_file(path: Path) -> None

Validate a COCO JSON file.

Checks
  • Required top-level keys present
  • All keypoint values finite (no NaN/Inf)
  • Visibility flags in {0, 1, 2}
  • Each annotation's image_id refers to an existing image
  • Each annotation has exactly 72 keypoint values (24 points x 3)
Source code in src/ue5_vehicle_synth/postprocess.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
def validate_coco_file(path: Path) -> None:
    """Validate a COCO JSON file.

    Checks:
        - Required top-level keys present
        - All keypoint values finite (no NaN/Inf)
        - Visibility flags in {0, 1, 2}
        - Each annotation's image_id refers to an existing image
        - Each annotation has exactly 72 keypoint values (24 points x 3)
    """
    data = json.loads(Path(path).read_text(encoding="utf-8"))

    for required_key in ("info", "images", "annotations", "categories"):
        if required_key not in data:
            raise PostprocessError(f"missing top-level key: {required_key}")

    image_ids = {img["id"] for img in data["images"]}

    for ann in data["annotations"]:
        if ann["image_id"] not in image_ids:
            raise PostprocessError(
                f"annotation {ann['id']} references unknown image_id {ann['image_id']}"
            )
        kpts = ann["keypoints"]
        if len(kpts) != 72:
            raise PostprocessError(
                f"annotation {ann['id']} has {len(kpts)} keypoint values, expected 72"
            )
        for i in range(0, 72, 3):
            x, y, v = kpts[i], kpts[i + 1], kpts[i + 2]
            if not (math.isfinite(x) and math.isfinite(y)):
                raise PostprocessError(
                    f"annotation {ann['id']} has non-finite keypoint at index {i // 3}"
                )
            if v not in (0, 1, 2):
                raise PostprocessError(
                    f"annotation {ann['id']} has bad visibility {v} at index {i // 3}"
                )
mask_offscreen_keypoints
mask_offscreen_keypoints(path: Path) -> None

Mutate a COCO file in place: any keypoint whose (x, y) lies outside the image bounds has its visibility set to 0.

Run AFTER validate_coco_file().

Source code in src/ue5_vehicle_synth/postprocess.py
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
def mask_offscreen_keypoints(path: Path) -> None:
    """Mutate a COCO file in place: any keypoint whose (x, y) lies outside the
    image bounds has its visibility set to 0.

    Run AFTER validate_coco_file().
    """
    data = json.loads(Path(path).read_text(encoding="utf-8"))
    images_by_id = {img["id"]: img for img in data["images"]}

    changed = False
    for ann in data["annotations"]:
        img = images_by_id[ann["image_id"]]
        w, h = img["width"], img["height"]
        kpts = ann["keypoints"]
        for i in range(0, 72, 3):
            x, y, v = kpts[i], kpts[i + 1], kpts[i + 2]
            if v == 0:
                continue
            if x < 0 or x >= w or y < 0 or y >= h:
                kpts[i + 2] = 0
                changed = True

    if changed:
        # recompute num_keypoints
        for ann in data["annotations"]:
            ann["num_keypoints"] = sum(1 for i in range(2, 72, 3) if ann["keypoints"][i] > 0)
        Path(path).write_text(json.dumps(data, indent=2), encoding="utf-8")

Schema

schema

24-pt extended vehicle keypoint schema.

The first 14 indices are the CarFusion canonical schema (verified against Occlusion-Net source); indices 14-23 are the extension defined in the spec.