Display of Annotation Type (#1192)

main
Priya4607 6 years ago committed by GitHub
parent a3448a20ad
commit 6a1e7af5c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -6,7 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [1.1.0-beta] - Unreleased
### Added
-
- Source type support for tags, shapes and tracks (<https://github.com/opencv/cvat/pull/1192>)
- Source type support for CVAT Dumper/Loader (<https://github.com/opencv/cvat/pull/1192>)
### Changed
- Smaller object details (<https://github.com/opencv/cvat/pull/1877>)

@ -189,7 +189,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
}
private onEditDone(state: any, points: number[]): void {
if (state && points) {
if (state && points) {
const event: CustomEvent = new CustomEvent('canvas.edited', {
bubbles: false,
cancelable: true,
@ -1732,14 +1732,14 @@ export class CanvasViewImpl implements CanvasView, Listener {
private addText(state: any): SVG.Text {
const { undefinedAttrValue } = this.configuration;
const { label, clientID, attributes } = state;
const { label, clientID, attributes, source } = state;
const attrNames = label.attributes.reduce((acc: any, val: any): void => {
acc[val.id] = val.name;
return acc;
}, {});
return this.adoptedText.text((block): void => {
block.tspan(`${label.name} ${clientID}`).style('text-transform', 'uppercase');
block.tspan(`${label.name} ${clientID} (${source})`).style('text-transform', 'uppercase');
for (const attrID of Object.keys(attributes)) {
const value = attributes[attrID] === undefinedAttrValue
? '' : attributes[attrID];

@ -402,6 +402,7 @@
frame: Math.min.apply(null, Object.keys(keyframes).map((frame) => +frame)),
shapes: Object.values(keyframes),
group: 0,
source: objectStates[0].source,
label_id: label.id,
attributes: Object.keys(objectStates[0].attributes)
.reduce((accumulator, attrID) => {
@ -763,6 +764,7 @@
points: [...state.points],
type: state.shapeType,
z_order: state.zOrder,
source: state.source,
});
} else if (state.objectType === 'track') {
constructed.tracks.push({
@ -770,6 +772,7 @@
.filter((attr) => !labelAttributes[attr.spec_id].mutable),
frame: state.frame,
group: 0,
source: state.source,
label_id: state.label.id,
shapes: [{
attributes: attributes

@ -183,6 +183,7 @@
this.removed = false;
this.lock = false;
this.color = color;
this.source = data.source;
this.updated = Date.now();
this.attributes = data.attributes.reduce((attributeAccumulator, attr) => {
attributeAccumulator[attr.spec_id] = attr.value;
@ -295,6 +296,21 @@
}, [this.clientID], frame);
}
_saveSource(source, frame) {
const undoSource = this.source;
const redoSource = source;
this.history.do(HistoryActions.CHANGED_SOURCE, () => {
this.source = undoSource;
this.updated = Date.now();
}, () => {
this.source = redoSource;
this.updated = Date.now();
}, [this.clientID], frame);
this.source = source;
}
_validateStateBeforeSave(frame, data, updated) {
let fittedPoints = [];
@ -381,6 +397,10 @@
}
}
if (updated.source) {
checkObjectType('source', data.source, 'string', null);
}
return fittedPoints;
}
@ -396,7 +416,8 @@
updateTimestamp(updated) {
const anyChanges = updated.label || updated.attributes || updated.points
|| updated.outside || updated.occluded || updated.keyframe
|| updated.zOrder || updated.hidden || updated.lock || updated.pinned;
|| updated.zOrder || updated.hidden || updated.lock || updated.pinned
|| updated.source;
if (anyChanges) {
this.updated = Date.now();
@ -492,6 +513,7 @@
frame: this.frame,
label_id: this.label.id,
group: this.group,
source: this.source,
};
}
@ -520,6 +542,7 @@
updated: this.updated,
pinned: this.pinned,
frame,
source: this.source,
};
}
@ -619,6 +642,10 @@
this._saveHidden(data.hidden, frame);
}
if (updated.source) {
this._saveSource(data.source, frame);
}
this.updateTimestamp(updated);
updated.reset();
@ -659,6 +686,7 @@
frame: this.frame,
label_id: this.label.id,
group: this.group,
source: this.source,
attributes: Object.keys(this.attributes).reduce((attributeAccumulator, attrId) => {
if (!labelAttributes[attrId].mutable) {
attributeAccumulator.push({
@ -726,6 +754,7 @@
last,
},
frame,
source: this.source,
};
}
@ -1034,6 +1063,7 @@
outside: current.outside,
occluded: current.occluded,
attributes: {},
source: current.source,
} : undefined;
if (redoShape) {
@ -1098,6 +1128,10 @@
this._saveAttributes(data.attributes, frame);
}
if (updated.source) {
this._saveSource(data.source, frame);
}
if (updated.keyframe) {
this._saveKeyframe(frame, data.keyframe);
}
@ -1164,6 +1198,7 @@
frame: this.frame,
label_id: this.label.id,
group: this.group,
source: this.source,
attributes: Object.keys(this.attributes).reduce((attributeAccumulator, attrId) => {
attributeAccumulator.push({
spec_id: attrId,
@ -1194,6 +1229,7 @@
color: this.color,
updated: this.updated,
frame,
source: this.source,
};
}
@ -1228,6 +1264,10 @@
this._saveColor(data.color, frame);
}
if (updated.source) {
this._saveSource(data.source, frame);
}
this.updateTimestamp(updated);
updated.reset();

@ -104,7 +104,7 @@
const keys = ['id', 'label_id', 'group', 'frame',
'occluded', 'z_order', 'points', 'type', 'shapes',
'attributes', 'value', 'spec_id', 'outside'];
'attributes', 'value', 'spec_id', 'source', 'outside'];
// Find created and updated objects
for (const type of Object.keys(exported)) {

@ -31,6 +31,7 @@ function build() {
LogType,
HistoryActions,
colors,
source,
} = require('./enums');
const {
@ -531,6 +532,7 @@ function build() {
LogType,
HistoryActions,
colors,
source,
},
/**
* Namespace is used for access to exceptions

@ -104,6 +104,20 @@
CUBOID: 'cuboid',
});
/**
* Annotation type
* @enum {string}
* @name source
* @memberof module:API.cvat.enums
* @property {string} MANUAL 'manual'
* @property {string} AUTO 'auto'
* @readonly
*/
const source = Object.freeze({
MANUAL:'manual',
AUTO:'auto',
});
/**
* Logger event types
* @enum {string}
@ -190,6 +204,7 @@
* @property {string} CHANGED_LOCK Changed lock
* @property {string} CHANGED_COLOR Changed color
* @property {string} CHANGED_HIDDEN Changed hidden
* @property {string} CHANGED_SOURCE Changed source
* @property {string} MERGED_OBJECTS Merged objects
* @property {string} SPLITTED_TRACK Splitted track
* @property {string} GROUPED_OBJECTS Grouped objects
@ -209,6 +224,7 @@
CHANGED_PINNED: 'Changed pinned',
CHANGED_COLOR: 'Changed color',
CHANGED_HIDDEN: 'Changed hidden',
CHANGED_SOURCE: 'Changed source',
MERGED_OBJECTS: 'Merged objects',
SPLITTED_TRACK: 'Splitted track',
GROUPED_OBJECTS: 'Grouped objects',
@ -241,5 +257,6 @@
LogType,
HistoryActions,
colors,
source,
};
})();

@ -22,7 +22,7 @@
* </br> Necessary fields: objectType, shapeType, frame, updated, group
* </br> Optional fields: keyframes, clientID, serverID
* </br> Optional fields which can be set later: points, zOrder, outside,
* occluded, hidden, attributes, lock, label, color, keyframe
* occluded, hidden, attributes, lock, label, color, keyframe, source
*/
constructor(serialized) {
const data = {
@ -39,6 +39,7 @@
color: null,
hidden: null,
pinned: null,
source: null,
keyframes: serialized.keyframes,
group: serialized.group,
updated: serialized.updated,
@ -68,6 +69,7 @@
this.lock = false;
this.color = false;
this.hidden = false;
this.source = false;
return reset;
},
@ -109,6 +111,20 @@
*/
get: () => data.shapeType,
},
source: {
/**
* @name source
* @type {module:API.cvat.enums.source}
* @memberof module:API.cvat.classes.ObjectState
* @readonly
* @instance
*/
get: () => data.source,
set: (source) => {
data.updateFlags.source = true;
data.source = source;
},
},
clientID: {
/**
* @name clientID
@ -343,6 +359,7 @@
this.label = serialized.label;
this.lock = serialized.lock;
this.source = serialized.source;
if (typeof (serialized.zOrder) === 'number') {
this.zOrder = serialized.zOrder;

@ -485,6 +485,7 @@ export function propagateObjectAsync(
label: objectState.label,
zOrder: objectState.zOrder,
frame: from,
source: objectState.source,
};
await sessionInstance.logger.log(

@ -324,6 +324,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
.filter((label: any) => label.id === activeLabelID)[0];
state.occluded = state.occluded || false;
state.frame = frame;
state.source = 'manual';
const objectState = new cvat.classes.ObjectState(state);
onCreateAnnotations(jobInstance, frame, [objectState]);
};
@ -500,6 +501,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
points,
} = event.detail;
state.points = points;
state.source = 'manual';
onUpdateAnnotations([state]);
};

@ -21,13 +21,13 @@ from .annotation import AnnotationManager, TrackManager
class TaskData:
Attribute = namedtuple('Attribute', 'name, value')
LabeledShape = namedtuple(
'LabeledShape', 'type, frame, label, points, occluded, attributes, group, z_order')
'LabeledShape', 'type, frame, label, points, occluded, attributes, source, group, z_order')
LabeledShape.__new__.__defaults__ = (0, 0)
TrackedShape = namedtuple(
'TrackedShape', 'type, frame, points, occluded, outside, keyframe, attributes, group, z_order, label, track_id')
TrackedShape.__new__.__defaults__ = (0, 0, None, 0)
Track = namedtuple('Track', 'label, group, shapes')
Tag = namedtuple('Tag', 'frame, label, attributes, group')
'TrackedShape', 'type, frame, points, occluded, outside, keyframe, attributes, source, group, z_order, label, track_id')
TrackedShape.__new__.__defaults__ = ('manual', 0, 0, None, 0)
Track = namedtuple('Track', 'label, group, source, shapes')
Tag = namedtuple('Tag', 'frame, label, attributes, source, group')
Tag.__new__.__defaults__ = (0, )
Frame = namedtuple(
'Frame', 'idx, frame, name, width, height, labeled_shapes, tags')
@ -217,6 +217,7 @@ class TaskData:
outside=shape.get("outside", False),
keyframe=shape.get("keyframe", True),
track_id=shape["track_id"],
source=shape.get("source", "manual"),
attributes=self._export_attributes(shape["attributes"]),
)
@ -229,6 +230,7 @@ class TaskData:
occluded=shape["occluded"],
z_order=shape.get("z_order", 0),
group=shape.get("group", 0),
source=shape["source"],
attributes=self._export_attributes(shape["attributes"]),
)
@ -237,6 +239,7 @@ class TaskData:
frame=self.abs_frame_id(tag["frame"]),
label=self._get_label_name(tag["label_id"]),
group=tag.get("group", 0),
source=tag["source"],
attributes=self._export_attributes(tag["attributes"]),
)
@ -290,11 +293,13 @@ class TaskData:
tracked_shape["attributes"] += track["attributes"]
tracked_shape["track_id"] = idx
tracked_shape["group"] = track["group"]
tracked_shape["source"] = track["source"]
tracked_shape["label_id"] = track["label_id"]
yield TaskData.Track(
label=self._get_label_name(track["label_id"]),
group=track["group"],
source=track["source"],
shapes=[self._export_tracked_shape(shape)
for shape in tracked_shapes],
)
@ -650,6 +655,7 @@ def import_dm_annotations(dm_dataset, task_data):
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()],
))
@ -658,6 +664,7 @@ def import_dm_annotations(dm_dataset, task_data):
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()],
))

@ -190,6 +190,7 @@ def dump_as_cvat_annotation(file_object, annotations):
dump_data = OrderedDict([
("label", shape.label),
("occluded", str(int(shape.occluded))),
("source", shape.source),
])
if shape.type == "rectangle":
@ -269,6 +270,7 @@ def dump_as_cvat_annotation(file_object, annotations):
for tag in frame_annotation.tags:
tag_data = OrderedDict([
("label", tag.label),
("source", tag.source),
])
if tag.group:
tag_data["group_id"] = str(tag.group)
@ -294,6 +296,7 @@ def dump_as_cvat_interpolation(file_object, annotations):
dump_data = OrderedDict([
("id", str(track_id)),
("label", track.label),
("source", track.source),
])
if track.group:
@ -385,6 +388,7 @@ def dump_as_cvat_interpolation(file_object, annotations):
dump_track(counter, annotations.Track(
label=shape.label,
group=shape.group,
source=shape.source,
shapes=[annotations.TrackedShape(
type=shape.type,
points=shape.points,
@ -430,6 +434,7 @@ def load(file_object, annotations):
track = annotations.Track(
label=el.attrib['label'],
group=int(el.attrib.get('group_id', 0)),
source=el.attrib.get('source', 'manual'),
shapes=[],
)
elif el.tag == 'image':
@ -448,6 +453,7 @@ def load(file_object, annotations):
'label': el.attrib['label'],
'group': int(el.attrib.get('group_id', 0)),
'attributes': attributes,
'source': str(el.attrib.get('source', 'manual'))
}
elif ev == 'end':
if el.tag == 'attribute' and attributes is not None:
@ -464,6 +470,7 @@ def load(file_object, annotations):
shape['frame'] = frame_id
shape['label'] = el.attrib['label']
shape['group'] = int(el.attrib.get('group_id', 0))
shape['source'] = str(el.attrib.get('source', 'manual'))
shape['type'] = 'rectangle' if el.tag == 'box' else el.tag
shape['occluded'] = el.attrib['occluded'] == '1'

@ -54,6 +54,7 @@ def _import(src_file, task_data):
group=0,
frame=frame_number,
attributes=[],
source='manual',
))
continue
@ -66,12 +67,13 @@ def _import(src_file, task_data):
z_order=ann.z_order,
frame=frame_number,
attributes=[],
source='manual',
)
# build trajectories as lists of shapes in track dict
if track_id not in tracks:
tracks[track_id] = task_data.Track(
label_cat.items[ann.label].name, 0, [])
label_cat.items[ann.label].name, 0, 'manual', [])
tracks[track_id].shapes.append(shape)
for track in tracks.values():

@ -381,6 +381,7 @@ class JobAnnotation:
'frame',
'label_id',
'group',
'source',
'labeledimageattributeval__spec_id',
'labeledimageattributeval__value',
'labeledimageattributeval__id',
@ -415,6 +416,7 @@ class JobAnnotation:
'type',
'frame',
'group',
'source',
'occluded',
'z_order',
'points',
@ -451,6 +453,7 @@ class JobAnnotation:
"frame",
"label_id",
"group",
"source",
"labeledtrackattributeval__spec_id",
"labeledtrackattributeval__value",
"labeledtrackattributeval__id",

@ -163,6 +163,7 @@ class TaskExportTest(_DbTestBase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": None,
"source": "manual",
"attributes": [
{
"spec_id": task["labels"][0]["attributes"][0]["id"],
@ -181,6 +182,7 @@ class TaskExportTest(_DbTestBase):
"frame": 1,
"label_id": task["labels"][1]["id"],
"group": None,
"source": "manual",
"attributes": [],
"points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3],
"type": "polygon",
@ -190,6 +192,7 @@ class TaskExportTest(_DbTestBase):
"frame": 1,
"label_id": task["labels"][0]["id"],
"group": 1,
"source": "manual",
"attributes": [],
"points": [100, 300.222, 400, 500, 1, 3],
"type": "points",
@ -199,6 +202,7 @@ class TaskExportTest(_DbTestBase):
"frame": 1,
"label_id": task["labels"][0]["id"],
"group": 1,
"source": "manual",
"attributes": [],
"points": [2.0, 2.1, 400, 500, 1, 3],
"type": "polyline",
@ -210,6 +214,7 @@ class TaskExportTest(_DbTestBase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": None,
"source": "manual",
"attributes": [
{
"spec_id": task["labels"][0]["attributes"][0]["id"],
@ -244,6 +249,7 @@ class TaskExportTest(_DbTestBase):
"frame": 1,
"label_id": task["labels"][1]["id"],
"group": None,
"source": "manual",
"attributes": [],
"shapes": [
{

@ -13,6 +13,7 @@ class TrackManagerTest(TestCase):
"frame": 0,
"label_id": 0,
"group": None,
"source": "manual",
"attributes": [],
"shapes": [
{
@ -44,6 +45,7 @@ class TrackManagerTest(TestCase):
"label_id": 0,
"group": None,
"attributes": [],
"source": "manual",
"shapes": [
{
"frame": 0,
@ -74,6 +76,7 @@ class TrackManagerTest(TestCase):
"label_id": 0,
"group": None,
"attributes": [],
"source": "manual",
"shapes": [
{
"frame": 0,
@ -104,6 +107,7 @@ class TrackManagerTest(TestCase):
"label_id": 0,
"group": None,
"attributes": [],
"source": "manual",
"shapes": [
{
"frame": 0,

@ -0,0 +1,28 @@
# Generated by Django 2.2.10 on 2020-07-19 15:52
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('engine', '0026_auto_20200719_1511'),
]
operations = [
migrations.AddField(
model_name='labeledimage',
name='source',
field=models.CharField(choices=[('auto', 'AUTO'), ('manual', 'MANUAL')], default='manual', max_length=16, null=True),
),
migrations.AddField(
model_name='labeledshape',
name='source',
field=models.CharField(choices=[('auto', 'AUTO'), ('manual', 'MANUAL')], default='manual', max_length=16, null=True),
),
migrations.AddField(
model_name='labeledtrack',
name='source',
field=models.CharField(choices=[('auto', 'AUTO'), ('manual', 'MANUAL')], default='manual', max_length=16, null=True),
),
]

@ -302,12 +302,24 @@ class ShapeType(str, Enum):
def __str__(self):
return self.value
class source(str, Enum):
AUTO = 'auto'
MANUAL = 'manual'
@classmethod
def choices(self):
return tuple((x.value, x.name) for x in self)
def __str__(self):
return self.value
class Annotation(models.Model):
id = models.BigAutoField(primary_key=True)
job = models.ForeignKey(Job, on_delete=models.CASCADE)
label = models.ForeignKey(Label, on_delete=models.CASCADE)
frame = models.PositiveIntegerField()
group = models.PositiveIntegerField(null=True)
source = models.CharField(max_length=16, choices=source.choices(), default="manual", null=True)
class Meta:
abstract = True

@ -409,6 +409,7 @@ class AnnotationSerializer(serializers.Serializer):
frame = serializers.IntegerField(min_value=0)
label_id = serializers.IntegerField(min_value=0)
group = serializers.IntegerField(min_value=0, allow_null=True)
source = serializers.CharField(default = 'manual')
class LabeledImageSerializer(AnnotationSerializer):
attributes = AttributeValSerializer(many=True,

@ -2100,6 +2100,7 @@ class JobAnnotationAPITestCase(APITestCase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": None,
"source": "manual",
"attributes": []
}
],
@ -2108,6 +2109,7 @@ class JobAnnotationAPITestCase(APITestCase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": None,
"source": "manual",
"attributes": [
{
"spec_id": task["labels"][0]["attributes"][0]["id"],
@ -2126,6 +2128,7 @@ class JobAnnotationAPITestCase(APITestCase):
"frame": 1,
"label_id": task["labels"][1]["id"],
"group": None,
"source": "manual",
"attributes": [],
"points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3],
"type": "polygon",
@ -2137,6 +2140,7 @@ class JobAnnotationAPITestCase(APITestCase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": None,
"source": "manual",
"attributes": [
{
"spec_id": task["labels"][0]["attributes"][0]["id"],
@ -2171,6 +2175,7 @@ class JobAnnotationAPITestCase(APITestCase):
"frame": 1,
"label_id": task["labels"][1]["id"],
"group": None,
"source": "manual",
"attributes": [],
"shapes": [
{
@ -2220,6 +2225,7 @@ class JobAnnotationAPITestCase(APITestCase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": None,
"source": "manual",
"attributes": []
}
],
@ -2228,6 +2234,7 @@ class JobAnnotationAPITestCase(APITestCase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": None,
"source": "manual",
"attributes": [
{
"spec_id": task["labels"][0]["attributes"][0]["id"],
@ -2240,16 +2247,17 @@ class JobAnnotationAPITestCase(APITestCase):
],
"points": [1.0, 2.1, 100, 300.222],
"type": "rectangle",
"occluded": False
"occluded": False,
},
{
"frame": 1,
"label_id": task["labels"][1]["id"],
"group": None,
"source": "manual",
"attributes": [],
"points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3],
"type": "polygon",
"occluded": False
"occluded": False,
},
],
"tracks": [
@ -2257,6 +2265,7 @@ class JobAnnotationAPITestCase(APITestCase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": None,
"source": "manual",
"attributes": [
{
"spec_id": task["labels"][0]["attributes"][0]["id"],
@ -2283,7 +2292,7 @@ class JobAnnotationAPITestCase(APITestCase):
"points": [2.0, 2.1, 100, 300.222],
"type": "rectangle",
"occluded": True,
"outside": True
"outside": True,
},
]
},
@ -2291,6 +2300,7 @@ class JobAnnotationAPITestCase(APITestCase):
"frame": 1,
"label_id": task["labels"][1]["id"],
"group": None,
"source": "manual",
"attributes": [],
"shapes": [
{
@ -2299,7 +2309,7 @@ class JobAnnotationAPITestCase(APITestCase):
"points": [1.0, 2.1, 100, 300.222],
"type": "rectangle",
"occluded": False,
"outside": False
"outside": False,
}
]
},
@ -2361,7 +2371,8 @@ class JobAnnotationAPITestCase(APITestCase):
"frame": 0,
"label_id": 11010101,
"group": None,
"attributes": []
"source": "manual",
"attributes": [],
}
],
"shapes": [
@ -2369,6 +2380,7 @@ class JobAnnotationAPITestCase(APITestCase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": None,
"source": "manual",
"attributes": [
{
"spec_id": 32234234,
@ -2381,16 +2393,17 @@ class JobAnnotationAPITestCase(APITestCase):
],
"points": [1.0, 2.1, 100, 300.222],
"type": "rectangle",
"occluded": False
"occluded": False,
},
{
"frame": 1,
"label_id": 1212121,
"group": None,
"source": "manual",
"attributes": [],
"points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3],
"type": "polygon",
"occluded": False
"occluded": False,
},
],
"tracks": [
@ -2398,6 +2411,7 @@ class JobAnnotationAPITestCase(APITestCase):
"frame": 0,
"label_id": 0,
"group": None,
"source": "manual",
"attributes": [],
"shapes": [
{
@ -2423,7 +2437,7 @@ class JobAnnotationAPITestCase(APITestCase):
"points": [2.0, 2.1, 100, 300.222],
"type": "rectangle",
"occluded": True,
"outside": True
"outside": True,
},
]
},
@ -2431,6 +2445,7 @@ class JobAnnotationAPITestCase(APITestCase):
"frame": 1,
"label_id": task["labels"][1]["id"],
"group": None,
"source": "manual",
"attributes": [],
"shapes": [
{
@ -2439,7 +2454,7 @@ class JobAnnotationAPITestCase(APITestCase):
"points": [1.0, 2.1, 100, 300.222],
"type": "rectangle",
"occluded": False,
"outside": False
"outside": False,
}
]
},
@ -2574,7 +2589,8 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": None,
"attributes": []
"source": "manual",
"attributes": [],
}
],
"shapes": [
@ -2582,6 +2598,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": None,
"source": "manual",
"attributes": [
{
"spec_id": task["labels"][0]["attributes"][0]["id"],
@ -2594,16 +2611,17 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
],
"points": [1.0, 2.1, 100, 300.222],
"type": "rectangle",
"occluded": False
"occluded": False,
},
{
"frame": 1,
"label_id": task["labels"][1]["id"],
"group": None,
"source": "manual",
"attributes": [],
"points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3],
"type": "polygon",
"occluded": False
"occluded": False,
},
],
"tracks": [
@ -2611,6 +2629,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": None,
"source": "manual",
"attributes": [
{
"spec_id": task["labels"][0]["attributes"][0]["id"],
@ -2637,7 +2656,8 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"points": [2.0, 2.1, 100, 300.222],
"type": "rectangle",
"occluded": True,
"outside": True
"outside": True,
},
]
},
@ -2645,6 +2665,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"frame": 1,
"label_id": task["labels"][1]["id"],
"group": None,
"source": "manual",
"attributes": [],
"shapes": [
{
@ -2653,7 +2674,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"points": [1.0, 2.1, 100, 300.222],
"type": "rectangle",
"occluded": False,
"outside": False
"outside": False,
}
]
},
@ -2694,7 +2715,8 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": None,
"attributes": []
"source": "manual",
"attributes": [],
}
],
"shapes": [
@ -2702,6 +2724,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": None,
"source": "manual",
"attributes": [
{
"spec_id": task["labels"][0]["attributes"][0]["id"],
@ -2714,16 +2737,17 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
],
"points": [1.0, 2.1, 100, 300.222],
"type": "rectangle",
"occluded": False
"occluded": False,
},
{
"frame": 1,
"label_id": task["labels"][1]["id"],
"group": None,
"source": "manual",
"attributes": [],
"points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3],
"type": "polygon",
"occluded": False
"occluded": False,
},
],
"tracks": [
@ -2731,6 +2755,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": None,
"source": "manual",
"attributes": [
{
"spec_id": task["labels"][0]["attributes"][0]["id"],
@ -2757,7 +2782,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"points": [2.0, 2.1, 100, 300.222],
"type": "rectangle",
"occluded": True,
"outside": True
"outside": True,
},
]
},
@ -2765,6 +2790,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"frame": 1,
"label_id": task["labels"][1]["id"],
"group": None,
"source": "manual",
"attributes": [],
"shapes": [
{
@ -2773,7 +2799,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"points": [1.0, 2.1, 100, 300.222],
"type": "rectangle",
"occluded": False,
"outside": False
"outside": False,
}
]
},
@ -2835,7 +2861,8 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"frame": 0,
"label_id": 11010101,
"group": None,
"attributes": []
"source": "manual",
"attributes": [],
}
],
"shapes": [
@ -2843,6 +2870,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": None,
"source": "manual",
"attributes": [
{
"spec_id": 32234234,
@ -2855,16 +2883,17 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
],
"points": [1.0, 2.1, 100, 300.222],
"type": "rectangle",
"occluded": False
"occluded": False,
},
{
"frame": 1,
"label_id": 1212121,
"group": None,
"source": "manual",
"attributes": [],
"points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3],
"type": "polygon",
"occluded": False
"occluded": False,
},
],
"tracks": [
@ -2872,6 +2901,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"frame": 0,
"label_id": 0,
"group": None,
"source": "manual",
"attributes": [],
"shapes": [
{
@ -2897,7 +2927,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"points": [2.0, 2.1, 100, 300.222],
"type": "rectangle",
"occluded": True,
"outside": True
"outside": True,
},
]
},
@ -2905,6 +2935,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"frame": 1,
"label_id": task["labels"][1]["id"],
"group": None,
"source": "manual",
"attributes": [],
"shapes": [
{
@ -2913,7 +2944,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"points": [1.0, 2.1, 100, 300.222],
"type": "rectangle",
"occluded": False,
"outside": False
"outside": False,
}
]
},
@ -2940,6 +2971,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": 0,
"source": "manual",
"attributes": [
{
"spec_id": task["labels"][0]["attributes"][0]["id"],
@ -2992,6 +3024,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"frame": 0,
"label_id": task["labels"][1]["id"],
"group": 0,
"source": "manual",
"attributes": [],
"shapes": [
{
@ -3000,7 +3033,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"points": [1.0, 2.1, 50.2, 36.6],
"type": "rectangle",
"occluded": False,
"outside": False
"outside": False,
},
{
"frame": 1,
@ -3016,7 +3049,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"points": [1.0, 2.1, 51, 36.6],
"type": "rectangle",
"occluded": False,
"outside": True
"outside": True,
}
]
}]
@ -3025,6 +3058,7 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
"frame": 0,
"label_id": task["labels"][0]["id"],
"group": 0,
"source": "manual",
"attributes": [
{
"spec_id": task["labels"][0]["attributes"][0]["id"],
@ -3037,33 +3071,36 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
],
"points": [1.0, 2.1, 10.6, 53.22],
"type": "rectangle",
"occluded": False
"occluded": False,
}]
rectangle_shapes_wo_attrs = [{
"frame": 1,
"label_id": task["labels"][1]["id"],
"group": 0,
"source": "manual",
"attributes": [],
"points": [2.0, 2.1, 40, 50.7],
"type": "rectangle",
"occluded": False
"occluded": False,
}]
polygon_shapes_wo_attrs = [{
"frame": 1,
"label_id": task["labels"][1]["id"],
"group": 0,
"source": "manual",
"attributes": [],
"points": [2.0, 2.1, 100, 30.22, 40, 77, 1, 3],
"type": "polygon",
"occluded": False
"occluded": False,
}]
polygon_shapes_with_attrs = [{
"frame": 2,
"label_id": task["labels"][0]["id"],
"group": 1,
"source": "manual",
"attributes": [
{
"spec_id": task["labels"][0]["attributes"][0]["id"],
@ -3076,28 +3113,31 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase):
],
"points": [20.0, 0.1, 10, 3.22, 4, 7, 10, 30, 1, 2, 4.44, 5.55],
"type": "polygon",
"occluded": True
"occluded": True,
},
{
"frame": 2,
"label_id": task["labels"][1]["id"],
"group": 1,
"source": "manual",
"attributes": [],
"points": [4, 7, 10, 30, 4, 5.55],
"type": "polygon",
"occluded": False
"occluded": False,
}]
tags_wo_attrs = [{
"frame": 2,
"label_id": task["labels"][1]["id"],
"group": 0,
"attributes": []
"source": "manual",
"attributes": [],
}]
tags_with_attrs = [{
"frame": 1,
"label_id": task["labels"][0]["id"],
"group": 3,
"source": "manual",
"attributes": [
{
"spec_id": task["labels"][0]["attributes"][0]["id"],

@ -174,6 +174,7 @@ def convert_to_cvat_format(data):
"group": None,
"occluded": False,
"attributes": [],
"source": "auto",
})
return result

Loading…
Cancel
Save