From 5cc099fae703ff06fc788577cca863cd77c7b026 Mon Sep 17 00:00:00 2001 From: Shabin Dilanchian Date: Thu, 24 Feb 2022 14:51:48 +0400 Subject: [PATCH 1/4] Update requirements.txt --- requirements.txt | 3 +- .../lib/core/usecases/annotations.py | 1 + src/superannotate/lib/core/video_convertor.py | 122 +++++++++--------- .../lib/infrastructure/services.py | 6 +- 4 files changed, 67 insertions(+), 65 deletions(-) diff --git a/requirements.txt b/requirements.txt index 17f91ada8..3df6a1d84 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,4 +18,5 @@ mixpanel==4.8.3 pydantic>=1.8.2 setuptools~=57.4.0 aiohttp==3.8.1 - +email-validator>=1.0.3 +nest-asyncio==1.5.4 diff --git a/src/superannotate/lib/core/usecases/annotations.py b/src/superannotate/lib/core/usecases/annotations.py index 28dea8209..a5faf61f1 100644 --- a/src/superannotate/lib/core/usecases/annotations.py +++ b/src/superannotate/lib/core/usecases/annotations.py @@ -547,6 +547,7 @@ def execute(self): reporter=self.reporter ) received_items_count = len(annotations) + self.reporter.finish_progress() if items_count > received_items_count: self.reporter.log_warning( f"Could not find annotations for {items_count - received_items_count}/{items_count} items." diff --git a/src/superannotate/lib/core/video_convertor.py b/src/superannotate/lib/core/video_convertor.py index e94f8c13b..b2aa21d10 100644 --- a/src/superannotate/lib/core/video_convertor.py +++ b/src/superannotate/lib/core/video_convertor.py @@ -1,3 +1,4 @@ +import math from collections import defaultdict from typing import Any from typing import Dict @@ -64,7 +65,7 @@ def interpolate_annotations( ): for idx, frame_idx in enumerate(range(from_frame, to_frame), 1): keyframe = False - if idx in (1, len(range(from_frame, to_frame))): + if idx == 1: keyframe = True points = None if annotation_type == "bbox": @@ -85,67 +86,64 @@ def interpolate_annotations( def _process(self): for instance in self._annotation_data["instances"]: - try: - for parameter in instance["parameters"]: - time_stamp_frame_map = [] - for timestamp in parameter["timestamps"]: - time_stamp_frame_map.append((round(timestamp["timestamp"] / self.ratio) + 1, timestamp)) - for idx, (frame_no, timestamp_data) in enumerate(time_stamp_frame_map): - annotation_type = instance["meta"]["type"] - try: - next_frame_no, next_timestamp = time_stamp_frame_map[idx + 1] - if frame_no == next_frame_no: - median = (timestamp_data["timestamp"] // self.ratio) + (self.ratio / 2) - if abs(median - timestamp_data["timestamp"]) < abs(median - next_timestamp["timestamp"]): - time_stamp_frame_map[idx + 1] = timestamp_data - continue - - frames_diff = next_frame_no - frame_no - steps = None - if annotation_type == "bbox": - if not frames_diff: - steps = { - "y1": 0, - "x2": 0, - "x1": 0, - "y2": 0 - } - else: - steps = { - "y1": round( - (next_timestamp["points"]["y1"] - timestamp_data["points"]["y1"]) / frames_diff, - 2), - "x2": round( - (next_timestamp["points"]["x2"] - timestamp_data["points"]["x2"]) / frames_diff, - 2), - "x1": round( - (next_timestamp["points"]["x1"] - timestamp_data["points"]["x1"]) / frames_diff, - 2), - "y2": round( - (next_timestamp["points"]["y2"] - timestamp_data["points"]["y2"]) / frames_diff, - 2), - } - self.interpolate_annotations( - class_name=instance["meta"]["className"], - from_frame=frame_no, - to_frame=next_frame_no, - data=timestamp_data, - steps=steps, - annotation_type=annotation_type - ) - except IndexError: - last_frame_no, last_timestamp = time_stamp_frame_map[-1] - end = round(parameter["end"] / self.ratio) - self.interpolate_annotations( - annotation_type=annotation_type, - class_name=instance["meta"]["className"], - from_frame=last_frame_no, - to_frame=end, - data=last_timestamp, - steps={"x1": 0, "y1": 0, "x2": 0, "y2": 0} - ) - except Exception as e: - pass + for parameter in instance["parameters"]: + time_stamp_frame_map = [] + for timestamp in parameter["timestamps"]: + time_stamp_frame_map.append((int(math.ceil(timestamp["timestamp"] / self.ratio)), timestamp)) + for idx, (frame_no, timestamp_data) in enumerate(time_stamp_frame_map): + annotation_type = instance["meta"]["type"] + try: + next_frame_no, next_timestamp = time_stamp_frame_map[idx + 1] + if frame_no == next_frame_no: + median = (timestamp_data["timestamp"] // self.ratio) + (self.ratio / 2) + if abs(median - timestamp_data["timestamp"]) < abs(median - next_timestamp["timestamp"]): + time_stamp_frame_map[idx + 1] = (frame_no, timestamp_data) + continue + + frames_diff = next_frame_no - frame_no + steps = None + if annotation_type == "bbox": + if not frames_diff: + steps = { + "y1": 0, + "x2": 0, + "x1": 0, + "y2": 0 + } + else: + steps = { + "y1": round( + (next_timestamp["points"]["y1"] - timestamp_data["points"]["y1"]) / frames_diff, + 2), + "x2": round( + (next_timestamp["points"]["x2"] - timestamp_data["points"]["x2"]) / frames_diff, + 2), + "x1": round( + (next_timestamp["points"]["x1"] - timestamp_data["points"]["x1"]) / frames_diff, + 2), + "y2": round( + (next_timestamp["points"]["y2"] - timestamp_data["points"]["y2"]) / frames_diff, + 2), + } + self.interpolate_annotations( + class_name=instance["meta"]["className"], + from_frame=frame_no, + to_frame=next_frame_no, + data=timestamp_data, + steps=steps, + annotation_type=annotation_type + ) + except IndexError: + # print(frame_no) + frame = self.get_frame(frame_no) + points = timestamp_data.get("points") + frame.annotations.append(Annotation( + type=annotation_type, + className=instance["meta"]["className"], + points=points, + attributes=timestamp_data.get("attributes"), + keyframe=True + )) def __iter__(self): for frame_no in range(1, int(self.frames_count) + 1): diff --git a/src/superannotate/lib/infrastructure/services.py b/src/superannotate/lib/infrastructure/services.py index b1eecc2b7..e1189d70a 100644 --- a/src/superannotate/lib/infrastructure/services.py +++ b/src/superannotate/lib/infrastructure/services.py @@ -1026,7 +1026,9 @@ def get_annotations( items: List[str], reporter: Reporter ) -> List[dict]: - get_limits_url = urljoin(self.assets_provider_url, self.URL_GET_ANNOTATIONS) + import nest_asyncio + nest_asyncio.apply() + query_params = { "team_id": team_id, "project_id": project_id, @@ -1038,7 +1040,7 @@ def get_annotations( loop = asyncio.new_event_loop() return loop.run_until_complete(handler.get_data( - url=get_limits_url, + url=urljoin(self.assets_provider_url, self.URL_GET_ANNOTATIONS), data=items, params=query_params, chunk_size=self.DEFAULT_CHUNK_SIZE, From 1eed548dc86415f74794c8bd76c972f284d98524 Mon Sep 17 00:00:00 2001 From: Shabin Dilanchian Date: Thu, 24 Feb 2022 16:52:17 +0400 Subject: [PATCH 2/4] Update version.py --- src/superannotate/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/superannotate/version.py b/src/superannotate/version.py index 638297ff0..9e6e22c6c 100644 --- a/src/superannotate/version.py +++ b/src/superannotate/version.py @@ -1 +1 @@ -__version__ = "4.3.0b13" +__version__ = "4.3.0b14" From 6ee988dbc1ca3e3e47998793322cec64f29ff677 Mon Sep 17 00:00:00 2001 From: Shabin Dilanchian Date: Thu, 24 Feb 2022 17:21:37 +0400 Subject: [PATCH 3/4] Fix cli annotation --- src/superannotate/lib/app/interface/cli_interface.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/superannotate/lib/app/interface/cli_interface.py b/src/superannotate/lib/app/interface/cli_interface.py index 9b28c89a2..6a3a0f3d9 100644 --- a/src/superannotate/lib/app/interface/cli_interface.py +++ b/src/superannotate/lib/app/interface/cli_interface.py @@ -187,6 +187,7 @@ def upload_annotations( def _upload_annotations( self, project, folder, format, dataset_name, task, pre=True ): + project_folder_name = project project_name, folder_name = split_project_path(project) project = controller.get_project_metadata(project_name=project_name).data if not format: @@ -213,11 +214,11 @@ def _upload_annotations( annotations_path = temp_dir if pre: upload_preannotations_from_folder_to_project( - project_name, annotations_path + project_folder_name, annotations_path ) else: upload_annotations_from_folder_to_project( - project_name, annotations_path + project_folder_name, annotations_path ) sys.exit(0) From c3db20fd949dd105096da52a67d276a8950064ba Mon Sep 17 00:00:00 2001 From: Vaghinak Basentsyan Date: Fri, 25 Feb 2022 11:05:11 +0400 Subject: [PATCH 4/4] fix converter merge issue --- src/superannotate/lib/core/video_convertor.py | 133 ++++++++++-------- 1 file changed, 71 insertions(+), 62 deletions(-) diff --git a/src/superannotate/lib/core/video_convertor.py b/src/superannotate/lib/core/video_convertor.py index ae58a6968..ffb92702d 100644 --- a/src/superannotate/lib/core/video_convertor.py +++ b/src/superannotate/lib/core/video_convertor.py @@ -1,3 +1,4 @@ +import math from collections import defaultdict from typing import Any from typing import Dict @@ -64,7 +65,7 @@ def interpolate_annotations( ): for idx, frame_idx in enumerate(range(from_frame, to_frame), 1): keyframe = False - if idx in (1, len(range(from_frame, to_frame))): + if idx == 1: keyframe = True points = None if annotation_type == "bbox": @@ -103,67 +104,75 @@ def _add_annotation( def _process(self): for instance in self._annotation_data["instances"]: - try: - for parameter in instance["parameters"]: - time_stamp_frame_map = [] - for timestamp in parameter["timestamps"]: - time_stamp_frame_map.append((round(timestamp["timestamp"] / self.ratio) + 1, timestamp)) - for idx, (frame_no, timestamp_data) in enumerate(time_stamp_frame_map): - annotation_type = instance["meta"]["type"] - try: - next_frame_no, next_timestamp = time_stamp_frame_map[idx + 1] - if frame_no == next_frame_no: - median = (timestamp_data["timestamp"] // self.ratio) + (self.ratio / 2) - if abs(median - timestamp_data["timestamp"]) < abs(median - next_timestamp["timestamp"]): - time_stamp_frame_map[idx + 1] = timestamp_data - continue - - frames_diff = next_frame_no - frame_no - steps = None - if annotation_type == "bbox": - if not frames_diff: - steps = { - "y1": 0, - "x2": 0, - "x1": 0, - "y2": 0 - } - else: - steps = { - "y1": round( - (next_timestamp["points"]["y1"] - timestamp_data["points"]["y1"]) / frames_diff, - 2), - "x2": round( - (next_timestamp["points"]["x2"] - timestamp_data["points"]["x2"]) / frames_diff, - 2), - "x1": round( - (next_timestamp["points"]["x1"] - timestamp_data["points"]["x1"]) / frames_diff, - 2), - "y2": round( - (next_timestamp["points"]["y2"] - timestamp_data["points"]["y2"]) / frames_diff, - 2), - } - self.interpolate_annotations( - class_name=instance["meta"]["className"], - from_frame=frame_no, - to_frame=next_frame_no, - data=timestamp_data, - steps=steps, - annotation_type=annotation_type - ) - except IndexError: - last_frame_no, last_timestamp = time_stamp_frame_map[-1] - end = round(parameter["end"] / self.ratio) - self.interpolate_annotations( - annotation_type=annotation_type, - class_name=instance["meta"]["className"], - from_frame=last_frame_no, - to_frame=end, - data=last_timestamp, - steps={"x1": 0, "y1": 0, "x2": 0, "y2": 0} - ) - except Exception as e: - pass + for parameter in instance["parameters"]: + time_stamp_frame_map = [] + for timestamp in parameter["timestamps"]: + time_stamp_frame_map.append((int(math.ceil(timestamp["timestamp"] / self.ratio)), timestamp)) + skip_current = False + for idx, (frame_no, timestamp_data) in enumerate(time_stamp_frame_map): + annotation_type = instance["meta"]["type"] + try: + next_frame_no, next_timestamp = time_stamp_frame_map[idx + 1] + if frame_no == next_frame_no: + median = (timestamp_data["timestamp"] // self.ratio) + (self.ratio / 2) + if abs(median - timestamp_data["timestamp"]) < abs( + median - next_timestamp["timestamp"]) and not skip_current: + time_stamp_frame_map[idx + 1] = (frame_no, timestamp_data) + self._add_annotation( + frame_no=frame_no, + annotation_type=annotation_type, + class_name=instance["meta"]["className"], + points=timestamp_data.get("points"), + attributes=timestamp_data.get("attributes"), + keyframe=True + ) + skip_current = True + elif skip_current: + frame_no += 1 + skip_current = False + + frames_diff = next_frame_no - frame_no + steps = None + if annotation_type == "bbox": + if not frames_diff: + steps = { + "y1": 0, + "x2": 0, + "x1": 0, + "y2": 0 + } + else: + steps = { + "y1": round( + (next_timestamp["points"]["y1"] - timestamp_data["points"]["y1"]) / frames_diff, + 2), + "x2": round( + (next_timestamp["points"]["x2"] - timestamp_data["points"]["x2"]) / frames_diff, + 2), + "x1": round( + (next_timestamp["points"]["x1"] - timestamp_data["points"]["x1"]) / frames_diff, + 2), + "y2": round( + (next_timestamp["points"]["y2"] - timestamp_data["points"]["y2"]) / frames_diff, + 2), + } + self.interpolate_annotations( + class_name=instance["meta"]["className"], + from_frame=frame_no, + to_frame=next_frame_no, + data=timestamp_data, + steps=steps, + annotation_type=annotation_type + ) + except IndexError: + frame = self.get_frame(frame_no) + frame.annotations.append(Annotation( + type=annotation_type, + className=instance["meta"]["className"], + points=timestamp_data.get("points"), + attributes=timestamp_data.get("attributes"), + keyframe=True + )) def __iter__(self): for frame_no in range(1, int(self.frames_count) + 1):