def it_uses_a_default_path_if_one_is_missing(tmp_path): content = """ { "image": { "original_filename": "P49-RediPad-ProPlayLEFTY_442.jpg", "filename": "P49-RediPad-ProPlayLEFTY_442.jpg" }, "annotations": [ { "keypoint": { "x": 207.97048950195312, "y": 449.39691162109375 }, "name": "left_knee" } ] } """ directory = tmp_path / "imports" directory.mkdir() import_file = directory / "darwin-file.json" import_file.write_text(content) annotation_file: dt.AnnotationFile = parse_darwin_json( import_file, None) assert annotation_file.remote_path == "/"
def split_video_annotations(self, release_name: str = "latest") -> None: release_dir: Path = self.local_path / "releases" / release_name annotations_path: Path = release_dir / "annotations" for count, annotation_file in enumerate( annotations_path.glob("*.json")): darwin_annotation: Optional[AnnotationFile] = parse_darwin_json( annotation_file, count) if not darwin_annotation or not darwin_annotation.is_video: continue frame_annotations = split_video_annotation(darwin_annotation) for frame_annotation in frame_annotations: annotation = build_image_annotation(frame_annotation) video_frame_annotations_path = annotations_path / annotation_file.stem video_frame_annotations_path.mkdir(exist_ok=True, parents=True) stem = Path(frame_annotation.filename).stem output_path = video_frame_annotations_path / f"{stem}.json" with output_path.open("w") as f: json.dump(annotation, f) # Finally delete video annotations annotation_file.unlink() # Update class list, which is used when loading local annotations in a dataset make_class_lists(release_dir)
def it_parses_darwin_images_correctly(tmp_path): content = """ { "image": { "width": 497, "height": 778, "original_filename": "P49-RediPad-ProPlayLEFTY_442.jpg", "filename": "P49-RediPad-ProPlayLEFTY_442.jpg", "url": "", "path": "/tmp_files" }, "annotations": [ { "keypoint": { "x": 207.97048950195312, "y": 449.39691162109375 }, "name": "left_knee" }, { "keypoint": { "x": 302.9606018066406, "y": 426.13946533203125 }, "name": "left_ankle" } ] } """ directory = tmp_path / "imports" directory.mkdir() import_file = directory / "darwin-file.json" import_file.write_text(content) annotation_file: dt.AnnotationFile = parse_darwin_json( import_file, None) assert annotation_file.path == import_file assert annotation_file.filename == "P49-RediPad-ProPlayLEFTY_442.jpg" assert len(annotation_file.annotations) == 2 assert len(annotation_file.annotation_classes) == 2 assert not annotation_file.is_video assert annotation_file.image_width == 497 assert annotation_file.image_height == 778 assert annotation_file.image_url == "" assert not annotation_file.workview_url assert not annotation_file.seq assert not annotation_file.frame_urls assert annotation_file.remote_path == "/tmp_files"
def darwin_to_dt_gen(file_paths): count = 0 for file_path in map(Path, file_paths): files = file_path.glob("**/*") if file_path.is_dir() else [file_path] for f in files: if f.suffix != ".json": continue data = parse_darwin_json(f, count) if data: if data.is_video: for d in split_video_annotation(data): yield d else: yield data count += 1
def it_returns_None_if_no_annotations_exist(tmp_path): content = """ { "image": { "width": 497, "height": 778, "original_filename": "P49-RediPad-ProPlayLEFTY_442.jpg", "filename": "P49-RediPad-ProPlayLEFTY_442.jpg", "url": "", "path": "/tmp_files" } } """ directory = tmp_path / "imports" directory.mkdir() import_file = directory / "darwin-file.json" import_file.write_text(content) annotation_file: dt.AnnotationFile = parse_darwin_json( import_file, None) assert not annotation_file
def parse_file(path: Path) -> Optional[dt.AnnotationFile]: if path.suffix != ".json": return return parse_darwin_json(path, 0)
def it_imports_multiple_skeletetons(tmp_path): content = """ { "dataset":"cars", "image":{ "filename":"ferrari-laferrari.jpg" }, "annotations":[ { "bounding_box":{ "h":547.0, "w":1709.0, "x":96.0, "y":437.0 }, "name":"car", "polygon":{ "path":[ { "x":1805.0, "y":586.0 }, { "x":1802.0, "y":586.0 }, { "x":1805.0, "y":588.0 } ] } }, { "name":"wheels", "skeleton":{ "nodes":[ { "name":"1", "occluded":false, "x":829.56, "y":824.5 }, { "name":"2", "occluded":false, "x":1670.5, "y":741.76 } ] } }, { "name":"door", "skeleton":{ "nodes":[ { "name":"1", "occluded":false, "x":867.86, "y":637.16 }, { "name":"2", "occluded":false, "x":1100.21, "y":810.09 }, { "name":"3", "occluded":false, "x":1298.45, "y":856.56 }, { "name":"4", "occluded":false, "x":1234.63, "y":492.12 } ] } } ] } """ directory = tmp_path / "imports" directory.mkdir() import_file = directory / "darwin-file.json" import_file.write_text(content) annotation_file: dt.AnnotationFile = parse_darwin_json( import_file, None) assert annotation_file.annotations[ 0].annotation_class.annotation_type == "polygon" assert annotation_file.annotations[ 1].annotation_class.annotation_type == "skeleton" assert annotation_file.annotations[ 2].annotation_class.annotation_type == "skeleton"
def it_parses_darwin_videos_correctly(tmp_path): content = """ { "dataset": "my-dataset", "image": { "width": 3840, "height": 2160, "fps": 0.0, "original_filename": "above tractor.mp4", "filename": "above tractor.mp4", "url": "https://my-website.com/api/videos/209/original", "path": "/", "workview_url": "https://my-website.com/workview?dataset=102&image=530", "frame_count": 343, "frame_urls": [ "https://my-website.com/api/videos/209/frames/0" ] }, "annotations": [ { "frames": { "3": { "bounding_box": { "h": 547.0, "w": 400.0, "x": 363.0, "y": 701.0 }, "instance_id": { "value": 119 }, "keyframe": true, "polygon": { "path": [ { "x": 748.0, "y": 732.0 }, { "x": 751.0, "y": 735.0 }, { "x": 748.0, "y": 733.0 } ] } } }, "interpolate_algorithm": "linear-1.1", "interpolated": true, "name": "Hand", "segments": [ [ 3, 46 ] ] } ] } """ directory = tmp_path / "imports" directory.mkdir() import_file = directory / "darwin-file.json" import_file.write_text(content) annotation_file: dt.AnnotationFile = parse_darwin_json( import_file, None) assert annotation_file.path == import_file assert annotation_file.filename == "above tractor.mp4" assert len(annotation_file.annotations) == 1 assert len(annotation_file.annotation_classes) == 1 assert annotation_file.is_video assert annotation_file.image_width == 3840 assert annotation_file.image_height == 2160 assert annotation_file.image_url == "https://my-website.com/api/videos/209/original" assert annotation_file.workview_url == "https://my-website.com/workview?dataset=102&image=530" assert not annotation_file.seq assert annotation_file.frame_urls == [ "https://my-website.com/api/videos/209/frames/0" ] assert annotation_file.remote_path == "/" assert annotation_file.annotations == [ dt.VideoAnnotation( annotation_class=dt.AnnotationClass( name="Hand", annotation_type="polygon", annotation_internal_type=None), frames={ 3: dt.Annotation( annotation_class=dt.AnnotationClass( name="Hand", annotation_type="polygon", annotation_internal_type=None), data={ "path": [{ "x": 748.0, "y": 732.0 }, { "x": 751.0, "y": 735.0 }, { "x": 748.0, "y": 733.0 }], "bounding_box": { "x": 363.0, "y": 701.0, "w": 400.0, "h": 547.0 }, }, subs=[ dt.SubAnnotation(annotation_type="instance_id", data=119) ], ) }, keyframes={3: True}, segments=[[3, 46]], interpolated=True, ) ]