Skip to content

Commit 2c5188f

Browse files
author
Maxim Zhiltsov
authored
Add label check on import (#2935)
* Add label check on import * include annotation type * update changelog * Make the message prettier
1 parent c3fb14b commit 2c5188f

File tree

3 files changed

+47
-27
lines changed

3 files changed

+47
-27
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3737
- Improved maintanance of popups visibility (<https://github.com/openvinotoolkit/cvat/pull/2809>)
3838
- Image visualizations settings on canvas for faster access (<https://github.com/openvinotoolkit/cvat/pull/2872>)
3939
- Better scale management of left panel when screen is too small (<https://github.com/openvinotoolkit/cvat/pull/2880>)
40+
- Improved error messages for annotation import (<https://github.com/openvinotoolkit/cvat/pull/2935>)
4041

4142
### Deprecated
4243

cvat/apps/dataset_manager/bindings.py

+34-26
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,9 @@ def convert_attrs(label, cvat_attrs):
601601

602602
return item_anno
603603

604+
class CvatImportError(Exception):
605+
pass
606+
604607
def match_dm_item(item, task_data, root_hint=None):
605608
is_video = task_data.meta['task']['mode'] == 'interpolation'
606609

@@ -615,8 +618,8 @@ def match_dm_item(item, task_data, root_hint=None):
615618
frame_number = cast(osp.basename(item.id)[len('frame_'):], int)
616619

617620
if not frame_number in task_data.frame_info:
618-
raise Exception("Could not match item id: '%s' with any task frame" %
619-
item.id)
621+
raise CvatImportError("Could not match item id: "
622+
"'%s' with any task frame" % item.id)
620623
return frame_number
621624

622625
def find_dataset_root(dm_dataset, task_data):
@@ -631,7 +634,6 @@ def find_dataset_root(dm_dataset, task_data):
631634
prefix = prefix[:-1]
632635
return prefix
633636

634-
635637
def import_dm_annotations(dm_dataset, task_data):
636638
shapes = {
637639
datumaro.AnnotationType.bbox: ShapeType.RECTANGLE,
@@ -667,26 +669,32 @@ def import_dm_annotations(dm_dataset, task_data):
667669
if 1 < s and group_map[g]}
668670
group_map = {g: i for i, g in enumerate([0] + sorted(group_map))}
669671

670-
for ann in item.annotations:
671-
if ann.type in shapes:
672-
task_data.add_shape(task_data.LabeledShape(
673-
type=shapes[ann.type],
674-
frame=frame_number,
675-
label=label_cat.items[ann.label].name,
676-
points=ann.points,
677-
occluded=ann.attributes.get('occluded') == True,
678-
z_order=ann.z_order,
679-
group=group_map.get(ann.group, 0),
680-
source='manual',
681-
attributes=[task_data.Attribute(name=n, value=str(v))
682-
for n, v in ann.attributes.items()],
683-
))
684-
elif ann.type == datumaro.AnnotationType.label:
685-
task_data.add_tag(task_data.Tag(
686-
frame=frame_number,
687-
label=label_cat.items[ann.label].name,
688-
group=group_map.get(ann.group, 0),
689-
source='manual',
690-
attributes=[task_data.Attribute(name=n, value=str(v))
691-
for n, v in ann.attributes.items()],
692-
))
672+
for idx, ann in enumerate(item.annotations):
673+
try:
674+
if hasattr(ann, 'label') and ann.label is None:
675+
raise CvatImportError("annotation has no label")
676+
if ann.type in shapes:
677+
task_data.add_shape(task_data.LabeledShape(
678+
type=shapes[ann.type],
679+
frame=frame_number,
680+
label=label_cat.items[ann.label].name,
681+
points=ann.points,
682+
occluded=ann.attributes.get('occluded') == True,
683+
z_order=ann.z_order,
684+
group=group_map.get(ann.group, 0),
685+
source='manual',
686+
attributes=[task_data.Attribute(name=n, value=str(v))
687+
for n, v in ann.attributes.items()],
688+
))
689+
elif ann.type == datumaro.AnnotationType.label:
690+
task_data.add_tag(task_data.Tag(
691+
frame=frame_number,
692+
label=label_cat.items[ann.label].name,
693+
group=group_map.get(ann.group, 0),
694+
source='manual',
695+
attributes=[task_data.Attribute(name=n, value=str(v))
696+
for n, v in ann.attributes.items()],
697+
))
698+
except Exception as e:
699+
raise CvatImportError("Image {}: can't import annotation "
700+
"#{} ({}): {}".format(item.id, idx, ann.type.name, e))

cvat/apps/engine/views.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import cvat.apps.dataset_manager as dm
3838
import cvat.apps.dataset_manager.views # pylint: disable=unused-import
3939
from cvat.apps.authentication import auth
40+
from cvat.apps.dataset_manager.bindings import CvatImportError
4041
from cvat.apps.dataset_manager.serializers import DatasetFormatsSerializer
4142
from cvat.apps.engine.frame_provider import FrameProvider
4243
from cvat.apps.engine.models import (
@@ -1030,7 +1031,17 @@ def _import_annotations(request, rq_id, rq_func, pk, format_name):
10301031
os.remove(rq_job.meta['tmp_file'])
10311032
exc_info = str(rq_job.exc_info)
10321033
rq_job.delete()
1033-
return Response(data=exc_info, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
1034+
1035+
# RQ adds a prefix with exception class name
1036+
import_error_prefix = '{}.{}'.format(
1037+
CvatImportError.__module__, CvatImportError.__name__)
1038+
if exc_info.startswith(import_error_prefix):
1039+
exc_info = exc_info.replace(import_error_prefix + ': ', '')
1040+
return Response(data=exc_info,
1041+
status=status.HTTP_400_BAD_REQUEST)
1042+
else:
1043+
return Response(data=exc_info,
1044+
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
10341045

10351046
return Response(status=status.HTTP_202_ACCEPTED)
10361047

0 commit comments

Comments
 (0)