Skip to content

Commit 148f769

Browse files
committed
update
1 parent 3054c03 commit 148f769

File tree

4 files changed

+185
-135
lines changed

4 files changed

+185
-135
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
from __future__ import annotations
2+
3+
import json
4+
from argparse import ArgumentParser
5+
from pathlib import Path
6+
from typing import Dict, Iterable, List
7+
8+
from labelformat.model.bounding_box import BoundingBox, BoundingBoxFormat
9+
from labelformat.model.category import Category
10+
from labelformat.model.object_detection_track import (
11+
ObjectDetectionTrackInput,
12+
SingleObjectDetectionTrack,
13+
VideoObjectDetectionTrack,
14+
)
15+
from labelformat.model.video import Video
16+
from labelformat.types import JsonDict
17+
18+
19+
class YouTubeVISObjectDetectionTrackInput(ObjectDetectionTrackInput):
20+
@staticmethod
21+
def add_cli_arguments(parser: ArgumentParser) -> None:
22+
parser.add_argument(
23+
"--input-file",
24+
type=Path,
25+
required=True,
26+
help="Path to input YouTube-VIS JSON file",
27+
)
28+
29+
def __init__(self, input_file: Path) -> None:
30+
with input_file.open() as file:
31+
self._data = json.load(file)
32+
33+
def get_categories(self) -> Iterable[Category]:
34+
for category in self._data["categories"]:
35+
yield Category(
36+
id=category["id"],
37+
name=category["name"],
38+
)
39+
40+
def get_videos(self) -> Iterable[Video]:
41+
for video in self._data["videos"]:
42+
yield Video(
43+
id=video["id"],
44+
# TODO (Jonas, 1/2026): The file_names do not hold the video file extension. Solution required.
45+
filename=Path(video["file_names"][0]).parent.name,
46+
width=int(video["width"]),
47+
height=int(video["height"]),
48+
number_of_frames=int(video["length"]),
49+
)
50+
51+
def get_labels(self) -> Iterable[VideoObjectDetectionTrack]:
52+
video_id_to_video = {video.id: video for video in self.get_videos()}
53+
category_id_to_category = {
54+
category.id: category for category in self.get_categories()
55+
}
56+
video_id_to_tracks: Dict[int, List[JsonDict]] = {
57+
video_id: [] for video_id in video_id_to_video.keys()
58+
}
59+
for ann in self._data["annotations"]:
60+
video_id_to_tracks[ann["video_id"]].append(ann)
61+
62+
for video_id, tracks in video_id_to_tracks.items():
63+
video = video_id_to_video[video_id]
64+
objects = []
65+
for track in tracks:
66+
boxes = _get_object_track_boxes(ann=track)
67+
objects.append(
68+
SingleObjectDetectionTrack(
69+
category=category_id_to_category[ann["category_id"]],
70+
boxes=boxes,
71+
)
72+
)
73+
yield VideoObjectDetectionTrack(
74+
video=video,
75+
objects=objects,
76+
)
77+
78+
79+
def _get_object_track_boxes(
80+
ann: JsonDict,
81+
) -> list[BoundingBox | None]:
82+
boxes: list[BoundingBox | None] = []
83+
for bbox in ann["bboxes"]:
84+
if bbox is None or len(bbox) == 0:
85+
boxes.append(None)
86+
else:
87+
boxes.append(
88+
BoundingBox.from_format(
89+
bbox=[float(x) for x in bbox],
90+
format=BoundingBoxFormat.XYWH,
91+
)
92+
)
93+
return boxes

src/labelformat/model/instance_segmentation_track.py

Lines changed: 0 additions & 67 deletions
This file was deleted.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import json
2+
from pathlib import Path
3+
4+
from labelformat.formats.youtubevis import YouTubeVISObjectDetectionTrackInput
5+
from labelformat.model.bounding_box import BoundingBox
6+
from labelformat.model.category import Category
7+
from labelformat.model.object_detection_track import (
8+
SingleObjectDetectionTrack,
9+
VideoObjectDetectionTrack,
10+
)
11+
from labelformat.model.video import Video
12+
13+
14+
class TestYouTubeVISObjectDetectionTrackInput:
15+
def test_get_categories(self, tmp_path: Path) -> None:
16+
input_file = _write_youtube_vis_json(tmp_path / "instances.json")
17+
label_input = YouTubeVISObjectDetectionTrackInput(input_file=input_file)
18+
19+
assert list(label_input.get_categories()) == [Category(id=1, name="cat")]
20+
21+
def test_get_videos(self, tmp_path: Path) -> None:
22+
input_file = _write_youtube_vis_json(tmp_path / "instances.json")
23+
label_input = YouTubeVISObjectDetectionTrackInput(input_file=input_file)
24+
25+
assert list(label_input.get_videos()) == [
26+
Video(
27+
id=5,
28+
filename="video1",
29+
width=640,
30+
height=480,
31+
number_of_frames=2,
32+
)
33+
]
34+
35+
def test_get_labels(self, tmp_path: Path) -> None:
36+
input_file = _write_youtube_vis_json(tmp_path / "instances.json")
37+
label_input = YouTubeVISObjectDetectionTrackInput(input_file=input_file)
38+
39+
assert list(label_input.get_labels()) == [
40+
VideoObjectDetectionTrack(
41+
video=Video(
42+
id=5,
43+
filename="video1",
44+
width=640,
45+
height=480,
46+
number_of_frames=2,
47+
),
48+
objects=[
49+
SingleObjectDetectionTrack(
50+
category=Category(id=1, name="cat"),
51+
boxes=[
52+
BoundingBox(
53+
xmin=10.0,
54+
ymin=20.0,
55+
xmax=40.0,
56+
ymax=60.0,
57+
),
58+
None,
59+
],
60+
)
61+
],
62+
)
63+
]
64+
65+
66+
def _write_youtube_vis_json(input_file: Path) -> Path:
67+
data = {
68+
"categories": [
69+
{"id": 1, "name": "cat"},
70+
],
71+
"videos": [
72+
{
73+
"id": 5,
74+
"file_names": ["video1/00000.jpg", "video1/00001.jpg"],
75+
"width": 640,
76+
"height": 480,
77+
"length": 2,
78+
}
79+
],
80+
"annotations": [
81+
{
82+
"video_id": 5,
83+
"category_id": 1,
84+
"bboxes": [
85+
[10.0, 20.0, 30.0, 40.0],
86+
None,
87+
],
88+
}
89+
],
90+
}
91+
input_file.write_text(json.dumps(data))
92+
return input_file

tests/unit/model/test_instance_segmentation_track.py

Lines changed: 0 additions & 68 deletions
This file was deleted.

0 commit comments

Comments
 (0)