diff --git a/packages/examples/cvat/exchange-oracle/src/core/tasks/boxes_from_points.py b/packages/examples/cvat/exchange-oracle/src/core/tasks/boxes_from_points.py index bd26aacc14..747d3a1c09 100644 --- a/packages/examples/cvat/exchange-oracle/src/core/tasks/boxes_from_points.py +++ b/packages/examples/cvat/exchange-oracle/src/core/tasks/boxes_from_points.py @@ -8,6 +8,8 @@ from attrs import frozen from datumaro.util import dump_json, parse_json +from src.core.tasks.roi_based import OUTPUT_OBJECT_ID_ATTR + BboxPointMapping = dict[int, int] @@ -90,3 +92,14 @@ def parse_roi_info(self, rois_info_data: bytes) -> RoiInfos: def parse_roi_filenames(self, roi_filenames_data: bytes) -> RoiFilenames: return {int(k): v for k, v in parse_json(roi_filenames_data).items()} + + +__all__ = [ + "OUTPUT_OBJECT_ID_ATTR", + "BboxPointMapping", + "RoiInfo", + "RoiInfos", + "RoiFilenames", + "TaskMetaLayout", + "TaskMetaSerializer", +] diff --git a/packages/examples/cvat/exchange-oracle/src/core/tasks/roi_based.py b/packages/examples/cvat/exchange-oracle/src/core/tasks/roi_based.py new file mode 100644 index 0000000000..b2d64a443c --- /dev/null +++ b/packages/examples/cvat/exchange-oracle/src/core/tasks/roi_based.py @@ -0,0 +1 @@ +OUTPUT_OBJECT_ID_ATTR = "object_id" diff --git a/packages/examples/cvat/exchange-oracle/src/core/tasks/skeletons_from_boxes.py b/packages/examples/cvat/exchange-oracle/src/core/tasks/skeletons_from_boxes.py index d48397e5d1..7459b904cb 100644 --- a/packages/examples/cvat/exchange-oracle/src/core/tasks/skeletons_from_boxes.py +++ b/packages/examples/cvat/exchange-oracle/src/core/tasks/skeletons_from_boxes.py @@ -9,6 +9,7 @@ from datumaro.util import dump_json, parse_json from src.core.config import Config +from src.core.tasks.roi_based import OUTPUT_OBJECT_ID_ATTR DEFAULT_ASSIGNMENT_SIZE_MULTIPLIER = Config.core_config.skeleton_assignment_size_mult @@ -133,3 +134,15 @@ def parse_point_labels(self, point_labels_data: bytes) -> PointLabelsMapping: (v["skeleton_label"], v["point_label"]): v["job_point_label"] for v in parse_json(point_labels_data) } + + +__all__ = [ + "OUTPUT_OBJECT_ID_ATTR", + "SkeletonBboxMapping", + "RoiInfo", + "RoiInfos", + "RoiFilenames", + "PointLabelsMapping", + "TaskMetaLayout", + "TaskMetaSerializer", +] diff --git a/packages/examples/cvat/exchange-oracle/src/handlers/job_export.py b/packages/examples/cvat/exchange-oracle/src/handlers/job_export.py index 1db5ae4be2..6b93567965 100644 --- a/packages/examples/cvat/exchange-oracle/src/handlers/job_export.py +++ b/packages/examples/cvat/exchange-oracle/src/handlers/job_export.py @@ -262,6 +262,18 @@ def _process_merged_dataset(self, input_dataset: Dataset) -> Dataset: ).elements[0] old_x, old_y = old_point.points[:2] + roi_anns = [ + roi_ann.wrap( + id=roi_info.point_id, + attributes={ + **roi_sample.attributes, + boxes_from_points_task.OUTPUT_OBJECT_ID_ATTR: roi_info.point_id, + }, + ) + for roi_ann in roi_sample.annotations + if isinstance(roi_ann, dm.Bbox) + ] + merged_sample.annotations.extend( annotation_utils.shift_ann( roi_ann, @@ -270,8 +282,7 @@ def _process_merged_dataset(self, input_dataset: Dataset) -> Dataset: img_w=image_w, img_h=image_h, ) - for roi_ann in roi_sample.annotations - if isinstance(roi_ann, dm.Bbox) + for roi_ann in roi_anns ) return merged_sample_dataset @@ -456,6 +467,7 @@ def _process_dataset(self, dataset: Dataset, *, ann_descriptor: FileDescriptor) ], label=self.bbox_label_to_merged[old_bbox.label], id=old_bbox.id, + attributes={skeletons_from_boxes_task.OUTPUT_OBJECT_ID_ATTR: old_bbox.id}, ) skeleton_sample.annotations.append(merged_skeleton) diff --git a/packages/examples/cvat/recording-oracle/src/core/config.py b/packages/examples/cvat/recording-oracle/src/core/config.py index 248f51cc6e..477046d0bf 100644 --- a/packages/examples/cvat/recording-oracle/src/core/config.py +++ b/packages/examples/cvat/recording-oracle/src/core/config.py @@ -177,6 +177,12 @@ class ValidationConfig: value small enough for faster convergence rate of the annotation process. """ + enable_gt_bans = to_bool(getenv("ENABLE_GT_BANS", "1")) + """ + Whether to allow automatic GT bans for bad images or not. By default, bans are allowed. + This can raise escrow annotation chances at the cost of reduced quality threshold. + """ + unverifiable_assignments_threshold = float(getenv("UNVERIFIABLE_ASSIGNMENTS_THRESHOLD", "0.1")) """ Deprecated. Not expected to happen in practice, kept only as a safety fallback rule. diff --git a/packages/examples/cvat/recording-oracle/src/handlers/process_intermediate_results.py b/packages/examples/cvat/recording-oracle/src/handlers/process_intermediate_results.py index 98d13d9cd7..74a1bde5ca 100644 --- a/packages/examples/cvat/recording-oracle/src/handlers/process_intermediate_results.py +++ b/packages/examples/cvat/recording-oracle/src/handlers/process_intermediate_results.py @@ -574,7 +574,8 @@ def _get_available_gt(self) -> tuple[GtStats, dict[int, set[GtKey]]]: gt_key for gt_key, gt_stat in self.gt_stats.items() if gt_stat.enabled - if gt_stat.rating > 1 - self.manifest.validation.min_quality + if not Config.validation.enable_gt_bans + or (gt_stat.rating > 1 - self.manifest.validation.min_quality) }, task_id_to_gt_keys def _check_warmup_annotation_speed(self):