未验证 提交 2c5188f5 编写于 作者: M Maxim Zhiltsov 提交者: GitHub

Add label check on import (#2935)

* Add label check on import

* include annotation type

* update changelog

* Make the message prettier
上级 c3fb14bf
......@@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Improved maintanance of popups visibility (<https://github.com/openvinotoolkit/cvat/pull/2809>)
- Image visualizations settings on canvas for faster access (<https://github.com/openvinotoolkit/cvat/pull/2872>)
- Better scale management of left panel when screen is too small (<https://github.com/openvinotoolkit/cvat/pull/2880>)
- Improved error messages for annotation import (<https://github.com/openvinotoolkit/cvat/pull/2935>)
### Deprecated
......
......@@ -601,6 +601,9 @@ class CvatTaskDataExtractor(datumaro.SourceExtractor):
return item_anno
class CvatImportError(Exception):
pass
def match_dm_item(item, task_data, root_hint=None):
is_video = task_data.meta['task']['mode'] == 'interpolation'
......@@ -615,8 +618,8 @@ def match_dm_item(item, task_data, root_hint=None):
frame_number = cast(osp.basename(item.id)[len('frame_'):], int)
if not frame_number in task_data.frame_info:
raise Exception("Could not match item id: '%s' with any task frame" %
item.id)
raise CvatImportError("Could not match item id: "
"'%s' with any task frame" % item.id)
return frame_number
def find_dataset_root(dm_dataset, task_data):
......@@ -631,7 +634,6 @@ def find_dataset_root(dm_dataset, task_data):
prefix = prefix[:-1]
return prefix
def import_dm_annotations(dm_dataset, task_data):
shapes = {
datumaro.AnnotationType.bbox: ShapeType.RECTANGLE,
......@@ -667,26 +669,32 @@ def import_dm_annotations(dm_dataset, task_data):
if 1 < s and group_map[g]}
group_map = {g: i for i, g in enumerate([0] + sorted(group_map))}
for ann in item.annotations:
if ann.type in shapes:
task_data.add_shape(task_data.LabeledShape(
type=shapes[ann.type],
frame=frame_number,
label=label_cat.items[ann.label].name,
points=ann.points,
occluded=ann.attributes.get('occluded') == True,
z_order=ann.z_order,
group=group_map.get(ann.group, 0),
source='manual',
attributes=[task_data.Attribute(name=n, value=str(v))
for n, v in ann.attributes.items()],
))
elif ann.type == datumaro.AnnotationType.label:
task_data.add_tag(task_data.Tag(
frame=frame_number,
label=label_cat.items[ann.label].name,
group=group_map.get(ann.group, 0),
source='manual',
attributes=[task_data.Attribute(name=n, value=str(v))
for n, v in ann.attributes.items()],
))
for idx, ann in enumerate(item.annotations):
try:
if hasattr(ann, 'label') and ann.label is None:
raise CvatImportError("annotation has no label")
if ann.type in shapes:
task_data.add_shape(task_data.LabeledShape(
type=shapes[ann.type],
frame=frame_number,
label=label_cat.items[ann.label].name,
points=ann.points,
occluded=ann.attributes.get('occluded') == True,
z_order=ann.z_order,
group=group_map.get(ann.group, 0),
source='manual',
attributes=[task_data.Attribute(name=n, value=str(v))
for n, v in ann.attributes.items()],
))
elif ann.type == datumaro.AnnotationType.label:
task_data.add_tag(task_data.Tag(
frame=frame_number,
label=label_cat.items[ann.label].name,
group=group_map.get(ann.group, 0),
source='manual',
attributes=[task_data.Attribute(name=n, value=str(v))
for n, v in ann.attributes.items()],
))
except Exception as e:
raise CvatImportError("Image {}: can't import annotation "
"#{} ({}): {}".format(item.id, idx, ann.type.name, e))
\ No newline at end of file
......@@ -37,6 +37,7 @@ from sendfile import sendfile
import cvat.apps.dataset_manager as dm
import cvat.apps.dataset_manager.views # pylint: disable=unused-import
from cvat.apps.authentication import auth
from cvat.apps.dataset_manager.bindings import CvatImportError
from cvat.apps.dataset_manager.serializers import DatasetFormatsSerializer
from cvat.apps.engine.frame_provider import FrameProvider
from cvat.apps.engine.models import (
......@@ -1030,7 +1031,17 @@ def _import_annotations(request, rq_id, rq_func, pk, format_name):
os.remove(rq_job.meta['tmp_file'])
exc_info = str(rq_job.exc_info)
rq_job.delete()
return Response(data=exc_info, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
# RQ adds a prefix with exception class name
import_error_prefix = '{}.{}'.format(
CvatImportError.__module__, CvatImportError.__name__)
if exc_info.startswith(import_error_prefix):
exc_info = exc_info.replace(import_error_prefix + ': ', '')
return Response(data=exc_info,
status=status.HTTP_400_BAD_REQUEST)
else:
return Response(data=exc_info,
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
return Response(status=status.HTTP_202_ACCEPTED)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册