From fd3e896cb06e25c42d66896af259ac5f95ded848 Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Mon, 23 Mar 2020 17:14:18 +0530 Subject: [PATCH 01/18] resolved merge conflicts --- cvat-canvas/src/typescript/canvasModel.ts | 1 + cvat-canvas/src/typescript/canvasView.ts | 35 +++++-- cvat-canvas/src/typescript/drawHandler.ts | 16 ++++ cvat-core/src/annotations-collection.js | 2 + cvat-core/src/annotations-objects.js | 93 +++++++++++++++++++ cvat-core/src/annotations-saver.js | 2 +- cvat-core/src/api.js | 2 + cvat-core/src/enums.js | 19 +++- cvat-core/src/object-state.js | 19 +++- .../standard-workspace/canvas-wrapper.tsx | 2 + 10 files changed, 181 insertions(+), 10 deletions(-) diff --git a/cvat-canvas/src/typescript/canvasModel.ts b/cvat-canvas/src/typescript/canvasModel.ts index f72bc6324701..765cc5d8a13b 100644 --- a/cvat-canvas/src/typescript/canvasModel.ts +++ b/cvat-canvas/src/typescript/canvasModel.ts @@ -47,6 +47,7 @@ export interface DrawData { numberOfPoints?: number; initialState?: any; crosshair?: boolean; + annotation_type?: string; } export interface EditData { diff --git a/cvat-canvas/src/typescript/canvasView.ts b/cvat-canvas/src/typescript/canvasView.ts index 5db41045586a..b89080b4fe40 100644 --- a/cvat-canvas/src/typescript/canvasView.ts +++ b/cvat-canvas/src/typescript/canvasView.ts @@ -37,6 +37,7 @@ import { Mode, Size, } from './canvasModel'; +import { isNullOrUndefined } from 'util'; export interface CanvasView { html(): HTMLDivElement; @@ -114,14 +115,15 @@ export class CanvasViewImpl implements CanvasView, Listener { } } - private onEditDone(state: any, points: number[]): void { - if (state && points) { + private onEditDone(state: any, points: number[], annotation_type: string): void { + if (state && points && annotation_type) { const event: CustomEvent = new CustomEvent('canvas.edited', { bubbles: false, cancelable: true, detail: { state, points, + annotation_type, }, }); @@ -433,9 +435,11 @@ export class CanvasViewImpl implements CanvasView, Listener { )); if (e.ctrlKey) { const { points } = state; + const annotation_type = 'Manual'; self.onEditDone( state, points.slice(0, pointID * 2).concat(points.slice(pointID * 2 + 2)), + annotation_type, ); } else if (e.shiftKey) { self.canvas.dispatchEvent(new CustomEvent('canvas.editstart', { @@ -859,6 +863,7 @@ export class CanvasViewImpl implements CanvasView, Listener { attributes: { ...state.attributes }, zOrder: state.zOrder, pinned: state.pinned, + annotation_type: state.annotation_type, }; } @@ -1174,7 +1179,8 @@ export class CanvasViewImpl implements CanvasView, Listener { id: state.clientID, }, })); - this.onEditDone(state, points); + const annotation_type = 'Manual'; + this.onEditDone(state, points, annotation_type); } }); } @@ -1222,6 +1228,7 @@ export class CanvasViewImpl implements CanvasView, Listener { + `${shape.attr('x') + shape.attr('width')},` + `${shape.attr('y') + shape.attr('height')}`, ).map((x: number): number => x - offset); + const annotation_type = 'Manual'; this.drawnStates[state.clientID].points = points; this.canvas.dispatchEvent(new CustomEvent('canvas.resizeshape', { @@ -1231,7 +1238,7 @@ export class CanvasViewImpl implements CanvasView, Listener { id: state.clientID, }, })); - this.onEditDone(state, points); + this.onEditDone(state, points, annotation_type); } }); @@ -1313,14 +1320,14 @@ export class CanvasViewImpl implements CanvasView, Listener { } private addText(state: any): SVG.Text { - const { label, clientID, attributes } = state; + const { label, clientID, attributes, annotation_type } = 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} (${annotation_type})`).style('text-transform', 'uppercase'); for (const attrID of Object.keys(attributes)) { block.tspan(`${attrNames[attrID]}: ${attributes[attrID]}`).attr({ attrID, @@ -1333,6 +1340,9 @@ export class CanvasViewImpl implements CanvasView, Listener { private addRect(points: number[], state: any): SVG.Rect { const [xtl, ytl, xbr, ybr] = points; + if (typeof (state.annotation_type) === 'undefined') { + state.annotation_type = 'Manual'; + } const rect = this.adoptedContent.rect().size(xbr - xtl, ybr - ytl).attr({ clientID: state.clientID, 'color-rendering': 'optimizeQuality', @@ -1342,6 +1352,7 @@ export class CanvasViewImpl implements CanvasView, Listener { stroke: state.color, 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, 'data-z-order': state.zOrder, + annotation_type: state.annotation_type, }).move(xtl, ytl) .addClass('cvat_canvas_shape'); @@ -1357,6 +1368,9 @@ export class CanvasViewImpl implements CanvasView, Listener { } private addPolygon(points: string, state: any): SVG.Polygon { + if (typeof (state.annotation_type) === 'undefined') { + state.annotation_type = 'Manual'; + } const polygon = this.adoptedContent.polygon(points).attr({ clientID: state.clientID, 'color-rendering': 'optimizeQuality', @@ -1366,6 +1380,7 @@ export class CanvasViewImpl implements CanvasView, Listener { stroke: state.color, 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, 'data-z-order': state.zOrder, + annotation_type: state.annotation_type, }).addClass('cvat_canvas_shape'); if (state.occluded) { @@ -1380,6 +1395,9 @@ export class CanvasViewImpl implements CanvasView, Listener { } private addPolyline(points: string, state: any): SVG.PolyLine { + if (typeof (state.annotation_type) === 'undefined') { + state.annotation_type = 'Manual'; + } const polyline = this.adoptedContent.polyline(points).attr({ clientID: state.clientID, 'color-rendering': 'optimizeQuality', @@ -1389,6 +1407,7 @@ export class CanvasViewImpl implements CanvasView, Listener { stroke: state.color, 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, 'data-z-order': state.zOrder, + annotation_type: state.annotation_type, }).addClass('cvat_canvas_shape'); if (state.occluded) { @@ -1424,12 +1443,14 @@ export class CanvasViewImpl implements CanvasView, Listener { } private addPoints(points: string, state: any): SVG.PolyLine { + state.annotation_type = 'Manual'; const shape = this.adoptedContent.polyline(points).attr({ 'color-rendering': 'optimizeQuality', 'pointer-events': 'none', 'shape-rendering': 'geometricprecision', 'stroke-width': 0, - fill: state.color, // to right fill property when call SVG.Shape::clone() + fill: state.color, // to right fill property when call SVG.Shape::clone( + annotation_type: state.annotation_type, }).style({ opacity: 0, }); diff --git a/cvat-canvas/src/typescript/drawHandler.ts b/cvat-canvas/src/typescript/drawHandler.ts index 4afe75ec259d..839146f45bb0 100644 --- a/cvat-canvas/src/typescript/drawHandler.ts +++ b/cvat-canvas/src/typescript/drawHandler.ts @@ -178,9 +178,11 @@ export class DrawHandlerImpl implements DrawHandler { this.cancel(); if ((xbr - xtl) * (ybr - ytl) >= consts.AREA_THRESHOLD) { + this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType, points: [xtl, ytl, xbr, ybr], + annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp); } }).on('drawupdate', (): void => { @@ -211,9 +213,11 @@ export class DrawHandlerImpl implements DrawHandler { this.cancel(); if ((xbr - xtl) * (ybr - ytl) >= consts.AREA_THRESHOLD) { + this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType, points: [xtl, ytl, xbr, ybr], + annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp); } } @@ -298,23 +302,29 @@ export class DrawHandlerImpl implements DrawHandler { if (shapeType === 'polygon' && ((box.xbr - box.xtl) * (box.ybr - box.ytl) >= consts.AREA_THRESHOLD) && points.length >= 3 * 2) { + this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType, points, + annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp); } else if (shapeType === 'polyline' && ((box.xbr - box.xtl) >= consts.SIZE_THRESHOLD || (box.ybr - box.ytl) >= consts.SIZE_THRESHOLD) && points.length >= 2 * 2) { + this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType, points, + annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp); } else if (shapeType === 'points' && (e.target as any).getAttribute('points') !== '0,0') { + this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType, points, + annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp); } }); @@ -358,6 +368,7 @@ export class DrawHandlerImpl implements DrawHandler { const { points } = this.getFinalPolyshapeCoordinates(targetPoints); this.release(); + this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType: this.drawData.initialState.shapeType, objectType: this.drawData.initialState.objectType, @@ -366,6 +377,7 @@ export class DrawHandlerImpl implements DrawHandler { attributes: { ...this.drawData.initialState.attributes }, label: this.drawData.initialState.label, color: this.drawData.initialState.color, + annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp, e.detail.originalEvent.ctrlKey); }); } @@ -398,6 +410,7 @@ export class DrawHandlerImpl implements DrawHandler { const bbox = this.drawInstance.node.getBBox(); const [xtl, ytl, xbr, ybr] = this.getFinalRectCoordinates(bbox); this.release(); + this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType: this.drawData.initialState.shapeType, objectType: this.drawData.initialState.objectType, @@ -406,6 +419,7 @@ export class DrawHandlerImpl implements DrawHandler { attributes: { ...this.drawData.initialState.attributes }, label: this.drawData.initialState.label, color: this.drawData.initialState.color, + annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp, e.detail.originalEvent.ctrlKey); }); } @@ -540,6 +554,7 @@ export class DrawHandlerImpl implements DrawHandler { if (this.drawData.initialState) { const { offset } = this.geometry; if (this.drawData.shapeType === 'rectangle') { + this.drawData.annotation_type = 'Manual'; const [xtl, ytl, xbr, ybr] = this.drawData.initialState.points .map((coord: number): number => coord + offset); @@ -566,6 +581,7 @@ export class DrawHandlerImpl implements DrawHandler { } else { if (this.drawData.shapeType === 'rectangle') { if (this.drawData.rectDrawingMethod === RectDrawingMethod.EXTREME_POINTS) { + this.drawData.annotation_type = 'Manual'; // draw box by extreme clicking this.drawBoxBy4Points(); } else { diff --git a/cvat-core/src/annotations-collection.js b/cvat-core/src/annotations-collection.js index 309d387d3122..ae80a4736944 100644 --- a/cvat-core/src/annotations-collection.js +++ b/cvat-core/src/annotations-collection.js @@ -748,6 +748,7 @@ points: [...state.points], type: state.shapeType, z_order: state.zOrder, + annotation_type: state.annotation_type, }); } else if (state.objectType === 'track') { constructed.tracks.push({ @@ -765,6 +766,7 @@ points: [...state.points], type: state.shapeType, z_order: state.zOrder, + annotation_type: state.annotation_type, }], }); } else { diff --git a/cvat-core/src/annotations-objects.js b/cvat-core/src/annotations-objects.js index 245d8e375c10..c4bf8f6df95d 100644 --- a/cvat-core/src/annotations-objects.js +++ b/cvat-core/src/annotations-objects.js @@ -19,6 +19,7 @@ ObjectType, AttributeType, HistoryActions, + AnnotationType, } = require('./enums'); const { @@ -149,6 +150,7 @@ this.removed = false; this.lock = false; this.color = color; + this.annotation_type = data.annotation_type; this.updated = Date.now(); this.attributes = data.attributes.reduce((attributeAccumulator, attr) => { attributeAccumulator[attr.spec_id] = attr.value; @@ -251,6 +253,19 @@ }, [this.clientID]); } + _saveAnnotationType(annotation_type) { + const undoannotation_type = this.annotation_type; + const redoannotation_type = annotation_type; + + this.history.do(HistoryActions.CHANGED_ANNOTATIONTYPE, () => { + this.annotation_type = undoannotation_type; + }, () => { + this.annotation_type = redoannotation_type; + }, [this.clientID]); + + this.annotation_type = annotation_type; + } + _validateStateBeforeSave(frame, data, updated) { let fittedPoints = []; @@ -346,6 +361,10 @@ } } + if (updated.annotation_type) { + checkObjectType('annotation_type', data.annotation_type, 'string', null); + } + return fittedPoints; } @@ -430,6 +449,7 @@ this.points = data.points; this.occluded = data.occluded; this.zOrder = data.z_order; + this.annotation_type = data.annotation_type; } // Method is used to export data to the server @@ -452,6 +472,7 @@ frame: this.frame, label_id: this.label.id, group: this.group, + annotation_type: this.annotation_type, }; } @@ -480,6 +501,7 @@ updated: this.updated, pinned: this.pinned, frame, + annotation_type:this.annotation_type, }; } @@ -522,6 +544,22 @@ this.zOrder = zOrder; } + _saveAnnotationType(annotation_type) { + const undoannotation_type = this.annotation_type; + const redoannotation_type = annotation_type; + + this.history.do(HistoryActions.CHANGED_ANNOTATIONTYPE, () => { + this.annotation_type = undoannotation_type; + }, () => { + this.annotation_type = redoannotation_type; + }, [this.clientID]); + + this.annotation_type = annotation_type; + } + + + + save(frame, data) { if (frame !== this.frame) { throw new ScriptingError( @@ -573,6 +611,10 @@ this._saveHidden(data.hidden); } + if (updated.annotation_type) { + this._saveAnnotationType(data.annotation_type); + } + this.updateTimestamp(updated); updated.reset(); @@ -590,6 +632,7 @@ zOrder: value.z_order, points: value.points, outside: value.outside, + annotation_type: value.annotation_type, attributes: value.attributes.reduce((attributeAccumulator, attr) => { attributeAccumulator[attr.spec_id] = attr.value; return attributeAccumulator; @@ -643,6 +686,7 @@ }, []), id: this.shapes[frame].serverID, frame: +frame, + annotation_type: this.annotation_type, }); return shapesAccumulator; @@ -680,6 +724,7 @@ last, }, frame, + annotation_type: this.annotation_type, }; } @@ -830,6 +875,7 @@ outside: current.outside, occluded: current.occluded, attributes: {}, + annotation_type: current.annotation_type, }; } } @@ -888,6 +934,7 @@ outside: current.outside, occluded: current.occluded, attributes: {}, + annotation_type: current.annotation_type, }; this.shapes[frame] = redoShape; @@ -910,6 +957,7 @@ points: current.points, occluded: current.occluded, attributes: {}, + annotation_type: current.annotation_type, }; this.shapes[frame] = redoShape; @@ -932,6 +980,7 @@ points: current.points, outside: current.outside, attributes: {}, + annotation_type: current.annotation_type, }; this.shapes[frame] = redoShape; @@ -954,6 +1003,7 @@ points: current.points, outside: current.outside, attributes: {}, + annotation_type: current.annotation_type, }; this.shapes[frame] = redoShape; @@ -965,6 +1015,29 @@ ); } + _saveAnnotationType(frame, annotation_type) { + const current = this.get(frame); + const wasKeyframe = frame in this.shapes; + const undoShape = wasKeyframe ? this.shapes[frame] : undefined; + const redoShape = wasKeyframe ? { ...this.shapes[frame], annotation_type } : { + frame, + annotation_type, + zOrder: current.zOrder, + points: current.points, + occluded: current.occluded, + outside: current.outside, + attributes: {}, + }; + + this.shapes[frame] = redoShape; + this._appendShapeActionToHistory( + HistoryActions.CHANGED_ANNOTATIONTYPE, + frame, + undoShape, + redoShape, + ); + } + _saveKeyframe(frame, keyframe) { const current = this.get(frame); const wasKeyframe = frame in this.shapes; @@ -982,6 +1055,7 @@ outside: current.outside, occluded: current.occluded, attributes: {}, + annotation_type: current.annotation_type, } : undefined; if (redoShape) { @@ -1046,6 +1120,10 @@ this._saveAttributes(frame, data.attributes); } + if (updated.annotation_type) { + this._saveAnnotationType(frame, data.annotation_type); + } + if (updated.keyframe) { this._saveKeyframe(frame, data.keyframe); } @@ -1102,6 +1180,7 @@ class Tag extends Annotation { constructor(data, clientID, color, injection) { super(data, clientID, color, injection); + this.annotation_type = data.annotation_type; } // Method is used to export data to the server @@ -1112,6 +1191,7 @@ frame: this.frame, label_id: this.label.id, group: this.group, + annotation_type: this.annotation_type, attributes: Object.keys(this.attributes).reduce((attributeAccumulator, attrId) => { attributeAccumulator.push({ spec_id: attrId, @@ -1142,6 +1222,7 @@ color: this.color, updated: this.updated, frame, + annotation_type: this.annotation_type, }; } @@ -1176,6 +1257,10 @@ this._saveColor(data.color); } + if (updated.annotation_type) { + this._saveAnnotationType(data.annotation_type); + } + this.updateTimestamp(updated); updated.reset(); @@ -1188,6 +1273,7 @@ super(data, clientID, color, injection); this.shapeType = ObjectShape.RECTANGLE; this.pinned = false; + this.annotation_type = data.annotation_type; checkNumberOfPoints(this.shapeType, this.points); } @@ -1214,6 +1300,7 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POLYGON; + this.annotation_type = data.annotation_type; checkNumberOfPoints(this.shapeType, this.points); } @@ -1289,6 +1376,7 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POLYLINE; + this.annotation_type = data.annotation_type; checkNumberOfPoints(this.shapeType, this.points); } @@ -1333,6 +1421,7 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POINTS; + this.annotation_type = data.annotation_type; checkNumberOfPoints(this.shapeType, this.points); } @@ -1356,6 +1445,7 @@ super(data, clientID, color, injection); this.shapeType = ObjectShape.RECTANGLE; this.pinned = false; + this.annotation_type = AnnotationType.MANUAL; for (const shape of Object.values(this.shapes)) { checkNumberOfPoints(this.shapeType, shape.points); } @@ -1774,6 +1864,7 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POLYGON; + this.annotation_type = AnnotationType.MANUAL; for (const shape of Object.values(this.shapes)) { checkNumberOfPoints(this.shapeType, shape.points); } @@ -1784,6 +1875,7 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POLYLINE; + this.annotation_type = AnnotationType.MANUAL; for (const shape of Object.values(this.shapes)) { checkNumberOfPoints(this.shapeType, shape.points); } @@ -1794,6 +1886,7 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POINTS; + this.annotation_type = AnnotationType.MANUAL; for (const shape of Object.values(this.shapes)) { checkNumberOfPoints(this.shapeType, shape.points); } diff --git a/cvat-core/src/annotations-saver.js b/cvat-core/src/annotations-saver.js index 42a07ecb39d4..d99e3370511e 100644 --- a/cvat-core/src/annotations-saver.js +++ b/cvat-core/src/annotations-saver.js @@ -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', 'annotation_type', 'outside']; // Find created and updated objects for (const type of Object.keys(exported)) { diff --git a/cvat-core/src/api.js b/cvat-core/src/api.js index 4eb4e99af00b..f1da5071889d 100644 --- a/cvat-core/src/api.js +++ b/cvat-core/src/api.js @@ -31,6 +31,7 @@ function build() { LogType, HistoryActions, colors, + AnnotationType, } = require('./enums'); const { @@ -529,6 +530,7 @@ function build() { LogType, HistoryActions, colors, + AnnotationType, }, /** * Namespace is used for access to exceptions diff --git a/cvat-core/src/enums.js b/cvat-core/src/enums.js index 8b6c86fcaab4..569575303529 100644 --- a/cvat-core/src/enums.js +++ b/cvat-core/src/enums.js @@ -102,9 +102,23 @@ POINTS: 'points', }); + /** + * Annotation type + * @enum {string} + * @name AnnotationType + * @memberof module:API.cvat.enums + * @property {string} MANUAL 'Manual' + * @property {string} AUTO 'Auto' + * @readonly + */ + const AnnotationType = Object.freeze({ + MANUAL:'Manual', + AUTO:'Auto', +}); + /** * Logger event types - * @enum {string} + * @enum {string} * @name LogType * @memberof module:API.cvat.enums * @property {string} loadJob Load job @@ -186,6 +200,7 @@ * @property {string} CHANGED_LOCK Changed lock * @property {string} CHANGED_COLOR Changed color * @property {string} CHANGED_HIDDEN Changed hidden + * @property {string} CHANGED_ANNOTATIONTYPE Changed annotation_type * @property {string} MERGED_OBJECTS Merged objects * @property {string} SPLITTED_TRACK Splitted track * @property {string} GROUPED_OBJECTS Grouped objects @@ -205,6 +220,7 @@ CHANGED_PINNED: 'Changed pinned', CHANGED_COLOR: 'Changed color', CHANGED_HIDDEN: 'Changed hidden', + CHANGED_ANNOTATIONTYPE: 'Changed annotation_type', MERGED_OBJECTS: 'Merged objects', SPLITTED_TRACK: 'Splitted track', GROUPED_OBJECTS: 'Grouped objects', @@ -236,5 +252,6 @@ LogType, HistoryActions, colors, + AnnotationType, }; })(); diff --git a/cvat-core/src/object-state.js b/cvat-core/src/object-state.js index e6a42f188afe..99453940ba9e 100644 --- a/cvat-core/src/object-state.js +++ b/cvat-core/src/object-state.js @@ -22,7 +22,7 @@ *
Necessary fields: objectType, shapeType, frame, updated, group *
Optional fields: keyframes, clientID, serverID *
Optional fields which can be set later: points, zOrder, outside, - * occluded, hidden, attributes, lock, label, color, keyframe + * occluded, hidden, attributes, lock, label, color, keyframe, annotation_type */ constructor(serialized) { const data = { @@ -39,6 +39,7 @@ color: null, hidden: null, pinned: null, + annotation_type: null, keyframes: serialized.keyframes, group: serialized.group, updated: serialized.updated, @@ -68,6 +69,7 @@ this.lock = false; this.color = false; this.hidden = false; + this.annotation_type = false; return reset; }, @@ -109,6 +111,20 @@ */ get: () => data.shapeType, }, + annotation_type: { + /** + * @name annotation_type + * @type {module:API.cvat.enums.AnnotationType} + * @memberof module:API.cvat.classes.ObjectState + * @readonly + * @instance + */ + get: () => data.annotation_type, + set: (annotation_type) => { + data.updateFlags.annotation_type = true; + data.annotation_type = annotation_type; + }, + }, clientID: { /** * @name clientID @@ -343,6 +359,7 @@ this.label = serialized.label; this.lock = serialized.lock; + this.annotation_type = serialized.annotation_type; if (typeof (serialized.zOrder) === 'number') { this.zOrder = serialized.zOrder; diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx index 16bc2e3ec144..ae2338ed9739 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx @@ -422,8 +422,10 @@ export default class CanvasWrapperComponent extends React.PureComponent { const { state, points, + annotation_type, } = event.detail; state.points = points; + state.annotation_type = annotation_type; onUpdateAnnotations([state]); }; From 1ec28693b99ce058e21818a610d89170d51193ba Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Mon, 23 Mar 2020 17:17:00 +0530 Subject: [PATCH 02/18] annotation_type field support for tags, tf_annotation api, cvat-dumper/loader --- cvat/apps/annotation/annotation.py | 9 ++++++--- cvat/apps/annotation/cvat.py | 6 ++++++ cvat/apps/engine/annotation.py | 3 +++ cvat/apps/engine/models.py | 12 ++++++++++++ cvat/apps/engine/serializers.py | 1 + cvat/apps/tf_annotation/views.py | 1 + 6 files changed, 29 insertions(+), 3 deletions(-) diff --git a/cvat/apps/annotation/annotation.py b/cvat/apps/annotation/annotation.py index 70054255c242..97066fd40324 100644 --- a/cvat/apps/annotation/annotation.py +++ b/cvat/apps/annotation/annotation.py @@ -102,12 +102,12 @@ def reset(self): class Annotation: Attribute = namedtuple('Attribute', 'name, value') - LabeledShape = namedtuple('LabeledShape', 'type, frame, label, points, occluded, attributes, group, z_order') + LabeledShape = namedtuple('LabeledShape', 'type, frame, label, points, occluded, attributes, group, z_order, annotation_type') LabeledShape.__new__.__defaults__ = (0, 0) - TrackedShape = namedtuple('TrackedShape', 'type, points, occluded, frame, attributes, outside, keyframe, z_order') + TrackedShape = namedtuple('TrackedShape', 'type, points, occluded, frame, attributes, outside, keyframe, z_order, annotation_type') TrackedShape.__new__.__defaults__ = (0, ) Track = namedtuple('Track', 'label, group, shapes') - Tag = namedtuple('Tag', 'frame, label, attributes, group') + Tag = namedtuple('Tag', 'frame, label, attributes, group, annotation_type') Tag.__new__.__defaults__ = (0, ) Frame = namedtuple('Frame', 'frame, name, width, height, labeled_shapes, tags') @@ -278,6 +278,7 @@ def _export_tracked_shape(self, shape): keyframe=shape.get("keyframe", True), z_order=shape["z_order"], attributes=self._export_attributes(shape["attributes"]), + annotation_type=shape.get("annotation_type", "Manual"), ) def _export_labeled_shape(self, shape): @@ -290,6 +291,7 @@ def _export_labeled_shape(self, shape): z_order=shape.get("z_order", 0), group=shape.get("group", 0), attributes=self._export_attributes(shape["attributes"]), + annotation_type=shape.get("annotation_type", "Manual"), ) def _export_tag(self, tag): @@ -298,6 +300,7 @@ def _export_tag(self, tag): label=self._get_label_name(tag["label_id"]), group=tag.get("group", 0), attributes=self._export_attributes(tag["attributes"]), + annotation_type=tag.get("annotation_type", "Manual"), ) def group_by_frame(self): diff --git a/cvat/apps/annotation/cvat.py b/cvat/apps/annotation/cvat.py index 4e89f2a437c1..4048ae409bd1 100644 --- a/cvat/apps/annotation/cvat.py +++ b/cvat/apps/annotation/cvat.py @@ -202,6 +202,7 @@ def dump_as_cvat_annotation(file_object, annotations): dump_data = OrderedDict([ ("label", shape.label), ("occluded", str(int(shape.occluded))), + ("annotation_type", shape.annotation_type), ]) if shape.type == "rectangle": @@ -281,6 +282,7 @@ def dump_as_cvat_annotation(file_object, annotations): for tag in frame_annotation.tags: tag_data = OrderedDict([ ("label", tag.label), + ("annotation_type", tag.annotation_type), ]) if tag.group: tag_data["group_id"] = str(tag.group) @@ -407,6 +409,7 @@ def dump_track(idx, track): z_order=shape.z_order, frame=shape.frame, attributes=shape.attributes, + annotation_type=shape.annotation_type, ), annotations.TrackedShape( type=shape.type, @@ -417,6 +420,7 @@ def dump_track(idx, track): z_order=shape.z_order, frame=shape.frame + annotations.frame_step, attributes=shape.attributes, + annotation_type=shape.annotation_type, ), ], )) @@ -461,6 +465,7 @@ def load(file_object, annotations): 'label': el.attrib['label'], 'group': int(el.attrib.get('group_id', 0)), 'attributes': attributes, + 'annotation_type': el.attrib["annotation_type"], } elif ev == 'end': if el.tag == 'attribute' and attributes is not None: @@ -481,6 +486,7 @@ def load(file_object, annotations): shape['type'] = 'rectangle' if el.tag == 'box' else el.tag shape['occluded'] = el.attrib['occluded'] == '1' shape['z_order'] = int(el.attrib.get('z_order', 0)) + shape['annotation_type'] = el.attrib.get('annotation_type', 'Manual') if el.tag == 'box': shape['points'].append(el.attrib['xtl']) diff --git a/cvat/apps/engine/annotation.py b/cvat/apps/engine/annotation.py index acb9a6d5e349..10aac8d62514 100644 --- a/cvat/apps/engine/annotation.py +++ b/cvat/apps/engine/annotation.py @@ -479,6 +479,7 @@ def _init_tags_from_db(self): 'frame', 'label_id', 'group', + 'annotation_type', 'labeledimageattributeval__spec_id', 'labeledimageattributeval__value', 'labeledimageattributeval__id', @@ -516,6 +517,7 @@ def _init_shapes_from_db(self): 'occluded', 'z_order', 'points', + 'annotation_type', 'labeledshapeattributeval__spec_id', 'labeledshapeattributeval__value', 'labeledshapeattributeval__id', @@ -549,6 +551,7 @@ def _init_tracks_from_db(self): "frame", "label_id", "group", + "annotation_type", "labeledtrackattributeval__spec_id", "labeledtrackattributeval__value", "labeledtrackattributeval__id", diff --git a/cvat/apps/engine/models.py b/cvat/apps/engine/models.py index a513cf5a107e..afaca544549a 100644 --- a/cvat/apps/engine/models.py +++ b/cvat/apps/engine/models.py @@ -258,12 +258,24 @@ def choices(self): def __str__(self): return self.value +class AnnotationType(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) + annotation_type = models.CharField(max_length=16, choices=AnnotationType.choices(), default="Manual", null=True) class Meta: abstract = True diff --git a/cvat/apps/engine/serializers.py b/cvat/apps/engine/serializers.py index e225dd23da6f..a8e3e2cde8f2 100644 --- a/cvat/apps/engine/serializers.py +++ b/cvat/apps/engine/serializers.py @@ -363,6 +363,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) + annotation_type = serializers.CharField(default = 'Manual') class LabeledImageSerializer(AnnotationSerializer): attributes = AttributeValSerializer(many=True, diff --git a/cvat/apps/tf_annotation/views.py b/cvat/apps/tf_annotation/views.py index 4aa0589cae63..0ccf90e1962a 100644 --- a/cvat/apps/tf_annotation/views.py +++ b/cvat/apps/tf_annotation/views.py @@ -188,6 +188,7 @@ def convert_to_cvat_format(data): "group": None, "occluded": False, "attributes": [], + "annotation_type": "Auto", }) return result From 98f1fd2dd0055294515d7bb65b4897a169b10ef1 Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Mon, 23 Mar 2020 17:17:47 +0530 Subject: [PATCH 03/18] unit test fix --- cvat/apps/engine/tests/test_rest_api.py | 120 ++++++++++++++++-------- 1 file changed, 83 insertions(+), 37 deletions(-) diff --git a/cvat/apps/engine/tests/test_rest_api.py b/cvat/apps/engine/tests/test_rest_api.py index f3da0410623c..76876b65774b 100644 --- a/cvat/apps/engine/tests/test_rest_api.py +++ b/cvat/apps/engine/tests/test_rest_api.py @@ -1704,7 +1704,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "attributes": [] + "attributes": [], + "annotation_type":"Manual" } ], "shapes": [ @@ -1724,7 +1725,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): ], "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", - "occluded": False + "occluded": False, + "annotation_type":"Manual" }, { "frame": 1, @@ -1733,7 +1735,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", - "occluded": False + "occluded": False, + "annotation_type":"Manual" }, ], "tracks": [ @@ -1754,6 +1757,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][1]["id"], @@ -1767,7 +1771,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "points": [2.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": True, - "outside": True + "outside": True, + "annotation_type": "Manual" }, ] }, @@ -1783,7 +1788,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": False, - "outside": False + "outside": False, + "annotation_type": "Manual" } ] }, @@ -1824,7 +1830,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "attributes": [] + "attributes": [], + "annotation_type":"Manual" } ], "shapes": [ @@ -1844,7 +1851,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): ], "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", - "occluded": False + "occluded": False, + "annotation_type": "Manual" }, { "frame": 1, @@ -1853,7 +1861,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", - "occluded": False + "occluded": False, + "annotation_type": "Manual" }, ], "tracks": [ @@ -1874,6 +1883,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][1]["id"], @@ -1887,7 +1897,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "points": [2.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": True, - "outside": True + "outside": True, + "annotation_type": "Manual" }, ] }, @@ -1903,7 +1914,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": False, - "outside": False + "outside": False, + "annotation_type": "Manual" } ] }, @@ -1965,7 +1977,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": 11010101, "group": None, - "attributes": [] + "attributes": [], + "annotation_type":"Manual" } ], "shapes": [ @@ -1985,7 +1998,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): ], "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", - "occluded": False + "occluded": False, + "annotation_type": "Manual" }, { "frame": 1, @@ -1994,7 +2008,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", - "occluded": False + "occluded": False, + "annotation_type": "Manual" }, ], "tracks": [ @@ -2010,6 +2025,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, + "annotation_type": "Manual", "attributes": [ { "spec_id": 10000, @@ -2027,7 +2043,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "points": [2.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": True, - "outside": True + "outside": True, + "annotation_type": "Manual" }, ] }, @@ -2043,7 +2060,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": False, - "outside": False + "outside": False, + "annotation_type": "Manual" } ] }, @@ -2173,7 +2191,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "attributes": [] + "attributes": [], + "annotation_type":"Manual" } ], "shapes": [ @@ -2193,7 +2212,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): ], "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", - "occluded": False + "occluded": False, + "annotation_type": "Manual" }, { "frame": 1, @@ -2202,7 +2222,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", - "occluded": False + "occluded": False, + "annotation_type": "Manual" }, ], "tracks": [ @@ -2223,6 +2244,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][1]["id"], @@ -2236,7 +2258,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "points": [2.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": True, - "outside": True + "outside": True, + "annotation_type": "Manual" }, ] }, @@ -2252,7 +2275,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": False, - "outside": False + "outside": False, + "annotation_type": "Manual" } ] }, @@ -2293,7 +2317,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "attributes": [] + "attributes": [], + "annotation_type":"Manual" } ], "shapes": [ @@ -2313,7 +2338,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): ], "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", - "occluded": False + "occluded": False, + "annotation_type": "Manual" }, { "frame": 1, @@ -2322,7 +2348,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", - "occluded": False + "occluded": False, + "annotation_type": "Manual" }, ], "tracks": [ @@ -2343,6 +2370,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][1]["id"], @@ -2356,7 +2384,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "points": [2.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": True, - "outside": True + "outside": True, + "annotation_type": "Manual" }, ] }, @@ -2372,7 +2401,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": False, - "outside": False + "outside": False, + "annotation_type": "Manual" } ] }, @@ -2434,7 +2464,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": 11010101, "group": None, - "attributes": [] + "attributes": [], + "annotation_type":"Manual" } ], "shapes": [ @@ -2454,7 +2485,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): ], "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", - "occluded": False + "occluded": False, + "annotation_type": "Manual" }, { "frame": 1, @@ -2463,7 +2495,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", - "occluded": False + "occluded": False, + "annotation_type": "Manual" }, ], "tracks": [ @@ -2479,6 +2512,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, + "annotation_type": "Manual", "attributes": [ { "spec_id": 10000, @@ -2496,7 +2530,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "points": [2.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": True, - "outside": True + "outside": True, + "annotation_type": "Manual" }, ] }, @@ -2512,7 +2547,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": False, - "outside": False + "outside": False, + "annotation_type": "Manual" } ] }, @@ -2552,6 +2588,7 @@ def _get_initial_annotation(annotation_format): "type": "rectangle", "occluded": False, "outside": False, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][1]["id"], @@ -2565,6 +2602,7 @@ def _get_initial_annotation(annotation_format): "type": "rectangle", "occluded": True, "outside": True, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][1]["id"], @@ -2586,7 +2624,8 @@ def _get_initial_annotation(annotation_format): "points": [1.0, 2.1, 50.2, 36.6], "type": "rectangle", "occluded": False, - "outside": False + "outside": False, + "annotation_type": "Manual" }, { "frame": 2, @@ -2594,7 +2633,8 @@ def _get_initial_annotation(annotation_format): "points": [1.0, 2.1, 51, 36.6], "type": "rectangle", "occluded": False, - "outside": True + "outside": True, + "annotation_type": "Manual" } ] }] @@ -2615,7 +2655,8 @@ def _get_initial_annotation(annotation_format): ], "points": [1.0, 2.1, 10.6, 53.22], "type": "rectangle", - "occluded": False + "occluded": False, + "annotation_type": "Manual" }] rectangle_shapes_wo_attrs = [{ @@ -2625,7 +2666,8 @@ def _get_initial_annotation(annotation_format): "attributes": [], "points": [2.0, 2.1, 40, 50.7], "type": "rectangle", - "occluded": False + "occluded": False, + "annotation_type": "Manual" }] polygon_shapes_wo_attrs = [{ @@ -2635,7 +2677,8 @@ def _get_initial_annotation(annotation_format): "attributes": [], "points": [2.0, 2.1, 100, 30.22, 40, 77, 1, 3], "type": "polygon", - "occluded": False + "occluded": False, + "annotation_type": "Manual" }] polygon_shapes_with_attrs = [{ @@ -2663,19 +2706,22 @@ def _get_initial_annotation(annotation_format): "attributes": [], "points": [4, 7, 10, 30, 4, 5.55], "type": "polygon", - "occluded": False + "occluded": False, + "annotation_type": "Manual" }] tags_wo_attrs = [{ "frame": 2, "label_id": task["labels"][1]["id"], "group": 0, - "attributes": [] + "attributes": [], + "annotation_type":"Manual" }] tags_with_attrs = [{ "frame": 1, "label_id": task["labels"][0]["id"], "group": 3, + "annotation_type":"Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], From 5c170c86b7408c27bb782e5c230242528037522b Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Mon, 23 Mar 2020 17:18:14 +0530 Subject: [PATCH 04/18] squashed migrations --- ...5_0657_squashed_0029_auto_20200309_0733.py | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 cvat/apps/engine/migrations/0024_auto_20200225_0657_squashed_0029_auto_20200309_0733.py diff --git a/cvat/apps/engine/migrations/0024_auto_20200225_0657_squashed_0029_auto_20200309_0733.py b/cvat/apps/engine/migrations/0024_auto_20200225_0657_squashed_0029_auto_20200309_0733.py new file mode 100644 index 000000000000..741334f69087 --- /dev/null +++ b/cvat/apps/engine/migrations/0024_auto_20200225_0657_squashed_0029_auto_20200309_0733.py @@ -0,0 +1,40 @@ +# Generated by Django 2.2.10 on 2020-03-22 19:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + replaces = [('engine', '0024_auto_20200225_0657'), ('engine', '0025_auto_20200306_0503'), ('engine', '0026_auto_20200306_0701'), ('engine', '0027_auto_20200306_1029'), ('engine', '0028_auto_20200309_0547'), ('engine', '0029_auto_20200309_0733')] + + dependencies = [ + ('engine', '0023_auto_20200113_1323'), + ] + + operations = [ + migrations.AddField( + model_name='labeledshape', + name='annotation_type', + field=models.CharField(choices=[('Auto', 'AUTO'), ('Manual', 'MANUAL')], default='Manual', max_length=16, null=True), + ), + migrations.AlterField( + model_name='labeledshape', + name='type', + field=models.CharField(choices=[('rectangle', 'RECTANGLE'), ('polygon', 'POLYGON'), ('polyline', 'POLYLINE'), ('points', 'POINTS'), ('cuboid', 'CUBOID')], max_length=16), + ), + migrations.AlterField( + model_name='trackedshape', + name='type', + field=models.CharField(choices=[('rectangle', 'RECTANGLE'), ('polygon', 'POLYGON'), ('polyline', 'POLYLINE'), ('points', 'POINTS'), ('cuboid', 'CUBOID')], max_length=16), + ), + migrations.AddField( + model_name='labeledimage', + name='annotation_type', + field=models.CharField(choices=[('Auto', 'AUTO'), ('Manual', 'MANUAL')], default='Manual', max_length=16, null=True), + ), + migrations.AddField( + model_name='labeledtrack', + name='annotation_type', + field=models.CharField(choices=[('Auto', 'AUTO'), ('Manual', 'MANUAL')], default='Manual', max_length=16, null=True), + ), + ] From 732f95ced320c5a78976f7a674a828f214a35905 Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Mon, 13 Apr 2020 23:54:11 +0530 Subject: [PATCH 05/18] updated CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f15c9608770..a70efb2ec242 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -253,6 +253,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Initial version +## [0.6.1] - 2020-04-14 +### Added +- Annotation type to determine whether a drawn shape is auto annotated using Tensorflow Object detection API or manually annotated by the user +- Annotation_type field support for cvat dumper/loader +- Annotation_type field support for tags + ## Template ``` ## [Unreleased] From b79deae76988bc55a7020913475db39ac83fa708 Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Mon, 13 Apr 2020 23:59:02 +0530 Subject: [PATCH 06/18] fixed unit test issues --- cvat/apps/annotation/annotation.py | 12 +-- cvat/apps/annotation/cvat.py | 6 +- cvat/apps/engine/tests/test_rest_api.py | 100 +++++++++++------------- 3 files changed, 55 insertions(+), 63 deletions(-) diff --git a/cvat/apps/annotation/annotation.py b/cvat/apps/annotation/annotation.py index 97066fd40324..136d34c059c2 100644 --- a/cvat/apps/annotation/annotation.py +++ b/cvat/apps/annotation/annotation.py @@ -102,13 +102,13 @@ def reset(self): class Annotation: Attribute = namedtuple('Attribute', 'name, value') - LabeledShape = namedtuple('LabeledShape', 'type, frame, label, points, occluded, attributes, group, z_order, annotation_type') - LabeledShape.__new__.__defaults__ = (0, 0) - TrackedShape = namedtuple('TrackedShape', 'type, points, occluded, frame, attributes, outside, keyframe, z_order, annotation_type') + LabeledShape = namedtuple('LabeledShape', 'type, frame, label, points, occluded, attributes, annotation_type, group, z_order') + LabeledShape.__new__.__defaults__ = ('Manual', 0, 0) + TrackedShape = namedtuple('TrackedShape', 'type, points, occluded, frame, attributes, outside, keyframe, z_order') TrackedShape.__new__.__defaults__ = (0, ) Track = namedtuple('Track', 'label, group, shapes') - Tag = namedtuple('Tag', 'frame, label, attributes, group, annotation_type') - Tag.__new__.__defaults__ = (0, ) + Tag = namedtuple('Tag', 'frame, label, attributes, annotation_type, group') + Tag.__new__.__defaults__ = ('Manual', 0) Frame = namedtuple('Frame', 'frame, name, width, height, labeled_shapes, tags') def __init__(self, annotation_ir, db_task, scheme='', host='', create_callback=None): @@ -278,7 +278,6 @@ def _export_tracked_shape(self, shape): keyframe=shape.get("keyframe", True), z_order=shape["z_order"], attributes=self._export_attributes(shape["attributes"]), - annotation_type=shape.get("annotation_type", "Manual"), ) def _export_labeled_shape(self, shape): @@ -348,6 +347,7 @@ def tracks(self): yield Annotation.Track( label=self._get_label_name(track["label_id"]), group=track['group'], + # annotation_type=track.get('annotation_type', 'Manual'), shapes=[self._export_tracked_shape(shape) for shape in tracked_shapes], ) diff --git a/cvat/apps/annotation/cvat.py b/cvat/apps/annotation/cvat.py index 4048ae409bd1..bcd938ebdedc 100644 --- a/cvat/apps/annotation/cvat.py +++ b/cvat/apps/annotation/cvat.py @@ -409,7 +409,6 @@ def dump_track(idx, track): z_order=shape.z_order, frame=shape.frame, attributes=shape.attributes, - annotation_type=shape.annotation_type, ), annotations.TrackedShape( type=shape.type, @@ -420,7 +419,6 @@ def dump_track(idx, track): z_order=shape.z_order, frame=shape.frame + annotations.frame_step, attributes=shape.attributes, - annotation_type=shape.annotation_type, ), ], )) @@ -465,7 +463,7 @@ def load(file_object, annotations): 'label': el.attrib['label'], 'group': int(el.attrib.get('group_id', 0)), 'attributes': attributes, - 'annotation_type': el.attrib["annotation_type"], + 'annotation_type': str(el.attrib.get('annotation_type', 'Manual')) } elif ev == 'end': if el.tag == 'attribute' and attributes is not None: @@ -482,11 +480,11 @@ def load(file_object, annotations): shape['frame'] = frame_id shape['label'] = el.attrib['label'] shape['group'] = int(el.attrib.get('group_id', 0)) + shape['annotation_type'] = str(el.attrib.get('annotation_type', 'Manual')) shape['type'] = 'rectangle' if el.tag == 'box' else el.tag shape['occluded'] = el.attrib['occluded'] == '1' shape['z_order'] = int(el.attrib.get('z_order', 0)) - shape['annotation_type'] = el.attrib.get('annotation_type', 'Manual') if el.tag == 'box': shape['points'].append(el.attrib['xtl']) diff --git a/cvat/apps/engine/tests/test_rest_api.py b/cvat/apps/engine/tests/test_rest_api.py index 76876b65774b..1247457e73d7 100644 --- a/cvat/apps/engine/tests/test_rest_api.py +++ b/cvat/apps/engine/tests/test_rest_api.py @@ -1704,8 +1704,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "attributes": [], - "annotation_type":"Manual" + "annotation_type": "Manual", + "attributes": [] } ], "shapes": [ @@ -1713,6 +1713,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -1725,18 +1726,17 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): ], "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", - "occluded": False, - "annotation_type":"Manual" + "occluded": False }, { "frame": 1, "label_id": task["labels"][1]["id"], "group": None, + "annotation_type": "Manual", "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", - "occluded": False, - "annotation_type":"Manual" + "occluded": False }, ], "tracks": [ @@ -1744,6 +1744,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -1757,7 +1758,6 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, - "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][1]["id"], @@ -1771,8 +1771,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "points": [2.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": True, - "outside": True, - "annotation_type": "Manual" + "outside": True }, ] }, @@ -1780,6 +1779,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, + "annotation_type": "Manual", "attributes": [], "shapes": [ { @@ -1788,8 +1788,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": False, - "outside": False, - "annotation_type": "Manual" + "outside": False } ] }, @@ -1830,8 +1829,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "attributes": [], - "annotation_type":"Manual" + "annotation_type": "Manual", + "attributes": [] } ], "shapes": [ @@ -1839,6 +1838,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -1852,17 +1852,16 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": False, - "annotation_type": "Manual" }, { "frame": 1, "label_id": task["labels"][1]["id"], "group": None, + "annotation_type": "Manual", "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", "occluded": False, - "annotation_type": "Manual" }, ], "tracks": [ @@ -1870,6 +1869,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -1883,7 +1883,6 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, - "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][1]["id"], @@ -1898,7 +1897,6 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": True, "outside": True, - "annotation_type": "Manual" }, ] }, @@ -1906,6 +1904,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, + "annotation_type": "Manual", "attributes": [], "shapes": [ { @@ -1915,7 +1914,6 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, - "annotation_type": "Manual" } ] }, @@ -1977,8 +1975,8 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": 11010101, "group": None, + "annotation_type": "Manual", "attributes": [], - "annotation_type":"Manual" } ], "shapes": [ @@ -1986,6 +1984,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, + "annotation_type": "Manual", "attributes": [ { "spec_id": 32234234, @@ -1999,17 +1998,16 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": False, - "annotation_type": "Manual" }, { "frame": 1, "label_id": 1212121, "group": None, + "annotation_type": "Manual", "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", "occluded": False, - "annotation_type": "Manual" }, ], "tracks": [ @@ -2017,6 +2015,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": 0, "group": None, + "annotation_type": "Manual", "attributes": [], "shapes": [ { @@ -2025,7 +2024,6 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, - "annotation_type": "Manual", "attributes": [ { "spec_id": 10000, @@ -2044,7 +2042,6 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": True, "outside": True, - "annotation_type": "Manual" }, ] }, @@ -2052,6 +2049,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, + "annotation_type": "Manual", "attributes": [], "shapes": [ { @@ -2061,7 +2059,6 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, - "annotation_type": "Manual" } ] }, @@ -2191,8 +2188,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, + "annotation_type": "Manual", "attributes": [], - "annotation_type":"Manual" } ], "shapes": [ @@ -2200,6 +2197,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -2213,17 +2211,16 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": False, - "annotation_type": "Manual" }, { "frame": 1, "label_id": task["labels"][1]["id"], "group": None, + "annotation_type": "Manual", "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", "occluded": False, - "annotation_type": "Manual" }, ], "tracks": [ @@ -2231,6 +2228,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -2244,7 +2242,6 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, - "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][1]["id"], @@ -2259,7 +2256,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": True, "outside": True, - "annotation_type": "Manual" + }, ] }, @@ -2267,6 +2264,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, + "annotation_type": "Manual", "attributes": [], "shapes": [ { @@ -2276,7 +2274,6 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, - "annotation_type": "Manual" } ] }, @@ -2317,8 +2314,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, + "annotation_type": "Manual", "attributes": [], - "annotation_type":"Manual" } ], "shapes": [ @@ -2326,6 +2323,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -2339,17 +2337,16 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": False, - "annotation_type": "Manual" }, { "frame": 1, "label_id": task["labels"][1]["id"], "group": None, + "annotation_type": "Manual", "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", "occluded": False, - "annotation_type": "Manual" }, ], "tracks": [ @@ -2357,6 +2354,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -2370,7 +2368,6 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, - "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][1]["id"], @@ -2385,7 +2382,6 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": True, "outside": True, - "annotation_type": "Manual" }, ] }, @@ -2393,6 +2389,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, + "annotation_type": "Manual", "attributes": [], "shapes": [ { @@ -2402,7 +2399,6 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, - "annotation_type": "Manual" } ] }, @@ -2464,8 +2460,8 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": 11010101, "group": None, + "annotation_type": "Manual", "attributes": [], - "annotation_type":"Manual" } ], "shapes": [ @@ -2473,6 +2469,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, + "annotation_type": "Manual", "attributes": [ { "spec_id": 32234234, @@ -2486,17 +2483,16 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "points": [1.0, 2.1, 100, 300.222], "type": "rectangle", "occluded": False, - "annotation_type": "Manual" }, { "frame": 1, "label_id": 1212121, "group": None, + "annotation_type": "Manual", "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", "occluded": False, - "annotation_type": "Manual" }, ], "tracks": [ @@ -2504,6 +2500,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": 0, "group": None, + "annotation_type": "Manual", "attributes": [], "shapes": [ { @@ -2512,7 +2509,6 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, - "annotation_type": "Manual", "attributes": [ { "spec_id": 10000, @@ -2531,7 +2527,6 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": True, "outside": True, - "annotation_type": "Manual" }, ] }, @@ -2539,6 +2534,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, + "annotation_type": "Manual", "attributes": [], "shapes": [ { @@ -2548,7 +2544,6 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "type": "rectangle", "occluded": False, "outside": False, - "annotation_type": "Manual" } ] }, @@ -2575,6 +2570,7 @@ def _get_initial_annotation(annotation_format): "frame": 0, "label_id": task["labels"][0]["id"], "group": 0, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -2588,7 +2584,6 @@ def _get_initial_annotation(annotation_format): "type": "rectangle", "occluded": False, "outside": False, - "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][1]["id"], @@ -2602,7 +2597,6 @@ def _get_initial_annotation(annotation_format): "type": "rectangle", "occluded": True, "outside": True, - "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][1]["id"], @@ -2616,6 +2610,7 @@ def _get_initial_annotation(annotation_format): "frame": 1, "label_id": task["labels"][1]["id"], "group": 0, + "annotation_type": "Manual", "attributes": [], "shapes": [ { @@ -2625,7 +2620,6 @@ def _get_initial_annotation(annotation_format): "type": "rectangle", "occluded": False, "outside": False, - "annotation_type": "Manual" }, { "frame": 2, @@ -2634,7 +2628,6 @@ def _get_initial_annotation(annotation_format): "type": "rectangle", "occluded": False, "outside": True, - "annotation_type": "Manual" } ] }] @@ -2643,6 +2636,7 @@ def _get_initial_annotation(annotation_format): "frame": 0, "label_id": task["labels"][0]["id"], "group": 0, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -2656,35 +2650,35 @@ def _get_initial_annotation(annotation_format): "points": [1.0, 2.1, 10.6, 53.22], "type": "rectangle", "occluded": False, - "annotation_type": "Manual" }] rectangle_shapes_wo_attrs = [{ "frame": 1, "label_id": task["labels"][1]["id"], "group": 0, + "annotation_type": "Manual", "attributes": [], "points": [2.0, 2.1, 40, 50.7], "type": "rectangle", "occluded": False, - "annotation_type": "Manual" }] polygon_shapes_wo_attrs = [{ "frame": 1, "label_id": task["labels"][1]["id"], "group": 0, + "annotation_type": "Manual", "attributes": [], "points": [2.0, 2.1, 100, 30.22, 40, 77, 1, 3], "type": "polygon", "occluded": False, - "annotation_type": "Manual" }] polygon_shapes_with_attrs = [{ "frame": 2, "label_id": task["labels"][0]["id"], "group": 1, + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -2697,31 +2691,31 @@ def _get_initial_annotation(annotation_format): ], "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, + "annotation_type": "Manual", "attributes": [], "points": [4, 7, 10, 30, 4, 5.55], "type": "polygon", "occluded": False, - "annotation_type": "Manual" }] tags_wo_attrs = [{ "frame": 2, "label_id": task["labels"][1]["id"], "group": 0, + "annotation_type": "Manual", "attributes": [], - "annotation_type":"Manual" }] tags_with_attrs = [{ "frame": 1, "label_id": task["labels"][0]["id"], "group": 3, - "annotation_type":"Manual", + "annotation_type": "Manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], From e21c824871fe69311d328c3224182e4d536dcdb2 Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Fri, 17 Apr 2020 22:55:20 +0530 Subject: [PATCH 07/18] minor fix --- cvat/apps/annotation/annotation.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cvat/apps/annotation/annotation.py b/cvat/apps/annotation/annotation.py index 2f5c804fcf8b..57ca09db521b 100644 --- a/cvat/apps/annotation/annotation.py +++ b/cvat/apps/annotation/annotation.py @@ -104,10 +104,6 @@ class Annotation: Attribute = namedtuple('Attribute', 'name, value') LabeledShape = namedtuple('LabeledShape', 'type, frame, label, points, occluded, attributes, annotation_type, group, z_order') LabeledShape.__new__.__defaults__ = ('Manual', 0, 0) - TrackedShape = namedtuple('TrackedShape', 'type, points, occluded, frame, attributes, outside, keyframe, z_order') - TrackedShape.__new__.__defaults__ = (0, ) - LabeledShape = namedtuple('LabeledShape', 'type, frame, label, points, occluded, attributes, 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') From 0405dbb6293f0821da2f0e90a8cde57bb846e562 Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Mon, 11 May 2020 21:37:52 +0530 Subject: [PATCH 08/18] eslint fix --- cvat-canvas/src/typescript/canvasModel.ts | 2 +- cvat-canvas/src/typescript/canvasView.ts | 46 ++++---- cvat-canvas/src/typescript/drawHandler.ts | 32 ++--- cvat-core/src/annotations-collection.js | 4 +- cvat-core/src/annotations-objects.js | 110 +++++++++--------- cvat-core/src/annotations-saver.js | 2 +- cvat-core/src/enums.js | 4 +- cvat-core/src/object-state.js | 20 ++-- .../standard-workspace/canvas-wrapper.tsx | 5 +- 9 files changed, 115 insertions(+), 110 deletions(-) diff --git a/cvat-canvas/src/typescript/canvasModel.ts b/cvat-canvas/src/typescript/canvasModel.ts index 08f4b162cd6c..c7513571a30b 100644 --- a/cvat-canvas/src/typescript/canvasModel.ts +++ b/cvat-canvas/src/typescript/canvasModel.ts @@ -60,7 +60,7 @@ export interface DrawData { numberOfPoints?: number; initialState?: any; crosshair?: boolean; - annotation_type?: string; + // annotation_type?: string; } export interface EditData { diff --git a/cvat-canvas/src/typescript/canvasView.ts b/cvat-canvas/src/typescript/canvasView.ts index e24f812b8e93..f3a425e6654a 100644 --- a/cvat-canvas/src/typescript/canvasView.ts +++ b/cvat-canvas/src/typescript/canvasView.ts @@ -116,7 +116,7 @@ export class CanvasViewImpl implements CanvasView, Listener { } } - private onEditDone(state: any, points: number[], annotation_type: string): void { + private onEditDone(state: any, points: number[]): void { if (state && points && annotation_type) { const event: CustomEvent = new CustomEvent('canvas.edited', { bubbles: false, @@ -124,7 +124,7 @@ export class CanvasViewImpl implements CanvasView, Listener { detail: { state, points, - annotation_type, + // annotation_type, }, }); @@ -445,11 +445,11 @@ export class CanvasViewImpl implements CanvasView, Listener { } if (e.ctrlKey) { const { points } = state; - const annotation_type = 'Manual'; + // const annotation_type = 'Manual'; self.onEditDone( state, points.slice(0, pointID * 2).concat(points.slice(pointID * 2 + 2)), - annotation_type, + // annotation_type, ); } else if (e.shiftKey) { self.canvas.dispatchEvent(new CustomEvent('canvas.editstart', { @@ -1023,7 +1023,7 @@ export class CanvasViewImpl implements CanvasView, Listener { attributes: { ...state.attributes }, zOrder: state.zOrder, pinned: state.pinned, - annotation_type: state.annotation_type, + // annotation_type: state.annotation_type, updated: state.updated, frame: state.frame, }; @@ -1380,8 +1380,8 @@ export class CanvasViewImpl implements CanvasView, Listener { id: state.clientID, }, })); - const annotation_type = 'Manual'; - this.onEditDone(state, points, annotation_type); + // const annotation_type = 'Manual'; + this.onEditDone(state, points); } }); } @@ -1429,7 +1429,7 @@ export class CanvasViewImpl implements CanvasView, Listener { + `${shape.attr('x') + shape.attr('width')},` + `${shape.attr('y') + shape.attr('height')}`, ).map((x: number): number => x - offset); - const annotation_type = 'Manual'; + // const annotation_type = 'Manual'; this.drawnStates[state.clientID].points = points; this.canvas.dispatchEvent(new CustomEvent('canvas.resizeshape', { @@ -1439,7 +1439,7 @@ export class CanvasViewImpl implements CanvasView, Listener { id: state.clientID, }, })); - this.onEditDone(state, points, annotation_type); + this.onEditDone(state, points); } }); @@ -1544,9 +1544,9 @@ export class CanvasViewImpl implements CanvasView, Listener { private addRect(points: number[], state: any): SVG.Rect { const [xtl, ytl, xbr, ybr] = points; - if (typeof (state.annotation_type) === 'undefined') { - state.annotation_type = 'Manual'; - } + // if (typeof (state.annotation_type) === 'undefined') { + // state.annotation_type = 'Manual'; + // } const rect = this.adoptedContent.rect().size(xbr - xtl, ybr - ytl).attr({ clientID: state.clientID, 'color-rendering': 'optimizeQuality', @@ -1556,7 +1556,7 @@ export class CanvasViewImpl implements CanvasView, Listener { stroke: state.color, 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, 'data-z-order': state.zOrder, - annotation_type: state.annotation_type, + // annotation_type: state.annotation_type, }).move(xtl, ytl) .addClass('cvat_canvas_shape'); @@ -1572,9 +1572,9 @@ export class CanvasViewImpl implements CanvasView, Listener { } private addPolygon(points: string, state: any): SVG.Polygon { - if (typeof (state.annotation_type) === 'undefined') { - state.annotation_type = 'Manual'; - } + // if (typeof (state.annotation_type) === 'undefined') { + // state.annotation_type = 'Manual'; + // } const polygon = this.adoptedContent.polygon(points).attr({ clientID: state.clientID, 'color-rendering': 'optimizeQuality', @@ -1584,7 +1584,7 @@ export class CanvasViewImpl implements CanvasView, Listener { stroke: state.color, 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, 'data-z-order': state.zOrder, - annotation_type: state.annotation_type, + // annotation_type: state.annotation_type, }).addClass('cvat_canvas_shape'); if (state.occluded) { @@ -1599,9 +1599,9 @@ export class CanvasViewImpl implements CanvasView, Listener { } private addPolyline(points: string, state: any): SVG.PolyLine { - if (typeof (state.annotation_type) === 'undefined') { - state.annotation_type = 'Manual'; - } + // if (typeof (state.annotation_type) === 'undefined') { + // state.annotation_type = 'Manual'; + // } const polyline = this.adoptedContent.polyline(points).attr({ clientID: state.clientID, 'color-rendering': 'optimizeQuality', @@ -1611,7 +1611,7 @@ export class CanvasViewImpl implements CanvasView, Listener { stroke: state.color, 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, 'data-z-order': state.zOrder, - annotation_type: state.annotation_type, + // annotation_type: state.annotation_type, }).addClass('cvat_canvas_shape'); if (state.occluded) { @@ -1674,14 +1674,14 @@ export class CanvasViewImpl implements CanvasView, Listener { } private addPoints(points: string, state: any): SVG.PolyLine { - state.annotation_type = 'Manual'; + // state.annotation_type = 'Manual'; const shape = this.adoptedContent.polyline(points).attr({ 'color-rendering': 'optimizeQuality', 'pointer-events': 'none', 'shape-rendering': 'geometricprecision', 'stroke-width': 0, fill: state.color, // to right fill property when call SVG.Shape::clone( - annotation_type: state.annotation_type, + // annotation_type: state.annotation_type, }).style({ opacity: 0, }); diff --git a/cvat-canvas/src/typescript/drawHandler.ts b/cvat-canvas/src/typescript/drawHandler.ts index bd43a58d8ae6..b9d5e17d54c8 100644 --- a/cvat-canvas/src/typescript/drawHandler.ts +++ b/cvat-canvas/src/typescript/drawHandler.ts @@ -267,11 +267,11 @@ export class DrawHandlerImpl implements DrawHandler { if (this.canceled) return; if ((xbr - xtl) * (ybr - ytl) >= consts.AREA_THRESHOLD) { - this.drawData.annotation_type = 'Manual'; + // this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType, points: [xtl, ytl, xbr, ybr], - annotation_type: this.drawData.annotation_type, + // annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp); } }).on('drawupdate', (): void => { @@ -302,11 +302,11 @@ export class DrawHandlerImpl implements DrawHandler { this.cancel(); if ((xbr - xtl) * (ybr - ytl) >= consts.AREA_THRESHOLD) { - this.drawData.annotation_type = 'Manual'; + // this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType, points: [xtl, ytl, xbr, ybr], - annotation_type: this.drawData.annotation_type, + // annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp); } } @@ -391,29 +391,29 @@ export class DrawHandlerImpl implements DrawHandler { if (shapeType === 'polygon' && ((box.xbr - box.xtl) * (box.ybr - box.ytl) >= consts.AREA_THRESHOLD) && points.length >= 3 * 2) { - this.drawData.annotation_type = 'Manual'; + // this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType, points, - annotation_type: this.drawData.annotation_type, + // annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp); } else if (shapeType === 'polyline' && ((box.xbr - box.xtl) >= consts.SIZE_THRESHOLD || (box.ybr - box.ytl) >= consts.SIZE_THRESHOLD) && points.length >= 2 * 2) { - this.drawData.annotation_type = 'Manual'; + // this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType, points, - annotation_type: this.drawData.annotation_type, + // annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp); } else if (shapeType === 'points' && (e.target as any).getAttribute('points') !== '0,0') { - this.drawData.annotation_type = 'Manual'; + // this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType, points, - annotation_type: this.drawData.annotation_type, + // annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp); // TODO: think about correct constraign for cuboids } else if (shapeType === 'cuboid' @@ -481,7 +481,7 @@ export class DrawHandlerImpl implements DrawHandler { if (!e.detail.originalEvent.ctrlKey) { this.release(); - this.drawData.annotation_type = 'Manual'; + // this.drawData.annotation_type = 'Manual'; } this.onDrawDone({ @@ -492,7 +492,7 @@ export class DrawHandlerImpl implements DrawHandler { attributes: { ...this.drawData.initialState.attributes }, label: this.drawData.initialState.label, color: this.drawData.initialState.color, - annotation_type: this.drawData.annotation_type, + // annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp, e.detail.originalEvent.ctrlKey); }); } @@ -526,7 +526,7 @@ export class DrawHandlerImpl implements DrawHandler { const [xtl, ytl, xbr, ybr] = this.getFinalRectCoordinates(bbox); if (!e.detail.originalEvent.ctrlKey) { this.release(); - this.drawData.annotation_type = 'Manual'; + // this.drawData.annotation_type = 'Manual'; } this.onDrawDone({ @@ -537,7 +537,7 @@ export class DrawHandlerImpl implements DrawHandler { attributes: { ...this.drawData.initialState.attributes }, label: this.drawData.initialState.label, color: this.drawData.initialState.color, - annotation_type: this.drawData.annotation_type, + // annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp, e.detail.originalEvent.ctrlKey); }); } @@ -650,7 +650,7 @@ export class DrawHandlerImpl implements DrawHandler { if (this.drawData.initialState) { const { offset } = this.geometry; if (this.drawData.shapeType === 'rectangle') { - this.drawData.annotation_type = 'Manual'; + // this.drawData.annotation_type = 'Manual'; const [xtl, ytl, xbr, ybr] = this.drawData.initialState.points .map((coord: number): number => coord + offset); @@ -679,7 +679,7 @@ export class DrawHandlerImpl implements DrawHandler { } else { if (this.drawData.shapeType === 'rectangle') { if (this.drawData.rectDrawingMethod === RectDrawingMethod.EXTREME_POINTS) { - this.drawData.annotation_type = 'Manual'; + // this.drawData.annotation_type = 'Manual'; // draw box by extreme clicking this.drawBoxBy4Points(); } else { diff --git a/cvat-core/src/annotations-collection.js b/cvat-core/src/annotations-collection.js index 24a3c6feee68..ce218ce3ae5b 100644 --- a/cvat-core/src/annotations-collection.js +++ b/cvat-core/src/annotations-collection.js @@ -763,7 +763,7 @@ points: [...state.points], type: state.shapeType, z_order: state.zOrder, - annotation_type: state.annotation_type, + annotation_type: state.annotationType, }); } else if (state.objectType === 'track') { constructed.tracks.push({ @@ -771,6 +771,7 @@ .filter((attr) => !labelAttributes[attr.spec_id].mutable), frame: state.frame, group: 0, + annotation_type: state.annotationType, label_id: state.label.id, shapes: [{ attributes: attributes @@ -781,7 +782,6 @@ points: [...state.points], type: state.shapeType, z_order: state.zOrder, - annotation_type: state.annotation_type, }], }); } else { diff --git a/cvat-core/src/annotations-objects.js b/cvat-core/src/annotations-objects.js index 67c262c13f83..fc3d5fd40632 100644 --- a/cvat-core/src/annotations-objects.js +++ b/cvat-core/src/annotations-objects.js @@ -185,7 +185,7 @@ this.removed = false; this.lock = false; this.color = color; - this.annotation_type = data.annotation_type; + this.annotationType = data.annotationType; this.updated = Date.now(); this.attributes = data.attributes.reduce((attributeAccumulator, attr) => { attributeAccumulator[attr.spec_id] = attr.value; @@ -298,17 +298,19 @@ }, [this.clientID], frame); } - _saveAnnotationType(annotation_type) { - const undoannotation_type = this.annotation_type; - const redoannotation_type = annotation_type; + _saveAnnotationType(annotationType, frame) { + const undoAnnotationType = this.annotationType; + const redoAnnotationType = annotationType; - this.history.do(HistoryActions.CHANGED_ANNOTATIONTYPE, () => { - this.annotation_type = undoannotation_type; + this.history.do(HistoryActions.CHANGED_ANNOTATION_TYPE, () => { + this.annotationType = undoAnnotationType; + this.updated = Date.now(); }, () => { - this.annotation_type = redoannotation_type; - }, [this.clientID]); + this.annotationType = redoAnnotationType; + this.updated = Date.now(); + }, [this.clientID], frame); - this.annotation_type = annotation_type; + this.annotationType = annotationType; } _validateStateBeforeSave(frame, data, updated) { @@ -395,8 +397,8 @@ } } - if (updated.annotation_type) { - checkObjectType('annotation_type', data.annotation_type, 'string', null); + if (updated.annotationType) { + checkObjectType('annotationType', data.annotationType, 'string', null); } return fittedPoints; @@ -414,7 +416,7 @@ 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.annotationType; if (anyChanges) { this.updated = Date.now(); @@ -488,7 +490,7 @@ this.points = data.points; this.occluded = data.occluded; this.zOrder = data.z_order; - this.annotation_type = data.annotation_type; + // this.annotationType = data.annotationType; } // Method is used to export data to the server @@ -511,7 +513,7 @@ frame: this.frame, label_id: this.label.id, group: this.group, - annotation_type: this.annotation_type, + annotation_type: this.annotationType, }; } @@ -540,7 +542,7 @@ updated: this.updated, pinned: this.pinned, frame, - annotation_type:this.annotation_type, + annotationType:this.annotationType, }; } @@ -589,17 +591,19 @@ this.zOrder = zOrder; } - _saveAnnotationType(annotation_type) { - const undoannotation_type = this.annotation_type; - const redoannotation_type = annotation_type; + _saveAnnotationType(annotationType, frame) { + const undoAnnotationType = this.annotationType; + const redoAnnotationType = annotationType; - this.history.do(HistoryActions.CHANGED_ANNOTATIONTYPE, () => { - this.annotation_type = undoannotation_type; + this.history.do(HistoryActions.CHANGED_ANNOTATION_TYPE, () => { + this.annotationType = undoAnnotationType; + this.updated = Date.now(); }, () => { - this.annotation_type = redoannotation_type; - }, [this.clientID]); + this.annotationType = redoAnnotationType; + this.updated = Date.now(); + }, [this.clientID], frame); - this.annotation_type = annotation_type; + this.annotationType = annotationType; } @@ -656,8 +660,8 @@ this._saveHidden(data.hidden, frame); } - if (updated.annotation_type) { - this._saveAnnotationType(data.annotation_type); + if (updated.annotationType) { + this._saveAnnotationType(data.annotationType); } this.updateTimestamp(updated); @@ -677,7 +681,7 @@ zOrder: value.z_order, points: value.points, outside: value.outside, - annotation_type: value.annotation_type, + // annotationType: value.annotationType, attributes: value.attributes.reduce((attributeAccumulator, attr) => { attributeAccumulator[attr.spec_id] = attr.value; return attributeAccumulator; @@ -701,6 +705,7 @@ frame: this.frame, label_id: this.label.id, group: this.group, + annotation_type: this.annotationType, attributes: Object.keys(this.attributes).reduce((attributeAccumulator, attrId) => { if (!labelAttributes[attrId].mutable) { attributeAccumulator.push({ @@ -731,7 +736,6 @@ }, []), id: this.shapes[frame].serverID, frame: +frame, - annotation_type: this.annotation_type, }); return shapesAccumulator; @@ -769,7 +773,7 @@ last, }, frame, - annotation_type: this.annotation_type, + annotationType: this.annotationType, }; } @@ -922,7 +926,7 @@ outside: current.outside, occluded: current.occluded, attributes: {}, - annotation_type: current.annotation_type, + annotationType: current.annotationType, }; } } @@ -985,7 +989,7 @@ outside: current.outside, occluded: current.occluded, attributes: {}, - annotation_type: current.annotation_type, + annotationType: current.annotationType, }; this.shapes[frame] = redoShape; @@ -1008,7 +1012,7 @@ points: current.points, occluded: current.occluded, attributes: {}, - annotation_type: current.annotation_type, + annotationType: current.annotationType, }; this.shapes[frame] = redoShape; @@ -1031,7 +1035,7 @@ points: current.points, outside: current.outside, attributes: {}, - annotation_type: current.annotation_type, + annotationType: current.annotationType, }; this.shapes[frame] = redoShape; @@ -1054,7 +1058,7 @@ points: current.points, outside: current.outside, attributes: {}, - annotation_type: current.annotation_type, + annotationType: current.annotationType, }; this.shapes[frame] = redoShape; @@ -1066,13 +1070,13 @@ ); } - _saveAnnotationType(frame, annotation_type) { + _saveAnnotationType(frame, annotationType) { const current = this.get(frame); const wasKeyframe = frame in this.shapes; const undoShape = wasKeyframe ? this.shapes[frame] : undefined; - const redoShape = wasKeyframe ? { ...this.shapes[frame], annotation_type } : { + const redoShape = wasKeyframe ? { ...this.shapes[frame], annotationType } : { frame, - annotation_type, + annotationType, zOrder: current.zOrder, points: current.points, occluded: current.occluded, @@ -1082,7 +1086,7 @@ this.shapes[frame] = redoShape; this._appendShapeActionToHistory( - HistoryActions.CHANGED_ANNOTATIONTYPE, + HistoryActions.CHANGED_ANNOTATION_TYPE, frame, undoShape, redoShape, @@ -1106,7 +1110,7 @@ outside: current.outside, occluded: current.occluded, attributes: {}, - annotation_type: current.annotation_type, + annotationType: current.annotationType, } : undefined; if (redoShape) { @@ -1171,8 +1175,8 @@ this._saveAttributes(data.attributes, frame); } - if (updated.annotation_type) { - this._saveAnnotationType(frame, data.annotation_type); + if (updated.annotationType) { + this._saveAnnotationType(frame, data.annotationType); } if (updated.keyframe) { @@ -1231,7 +1235,7 @@ class Tag extends Annotation { constructor(data, clientID, color, injection) { super(data, clientID, color, injection); - this.annotation_type = data.annotation_type; + // this.annotationType = data.annotationType; } // Method is used to export data to the server @@ -1242,7 +1246,7 @@ frame: this.frame, label_id: this.label.id, group: this.group, - annotation_type: this.annotation_type, + annotationType: this.annotationType, attributes: Object.keys(this.attributes).reduce((attributeAccumulator, attrId) => { attributeAccumulator.push({ spec_id: attrId, @@ -1273,7 +1277,7 @@ color: this.color, updated: this.updated, frame, - annotation_type: this.annotation_type, + annotationType: this.annotationType, }; } @@ -1308,8 +1312,8 @@ this._saveColor(data.color, frame); } - if (updated.annotation_type) { - this._saveAnnotationType(data.annotation_type); + if (updated.annotationType) { + this._saveAnnotationType(data.annotationType, frame); } this.updateTimestamp(updated); @@ -1324,7 +1328,7 @@ super(data, clientID, color, injection); this.shapeType = ObjectShape.RECTANGLE; this.pinned = false; - this.annotation_type = data.annotation_type; + // this.annotationType = data.annotationType; checkNumberOfPoints(this.shapeType, this.points); } @@ -1351,7 +1355,7 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POLYGON; - this.annotation_type = data.annotation_type; + // this.annotationType = data.annotationType; checkNumberOfPoints(this.shapeType, this.points); } @@ -1427,7 +1431,7 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POLYLINE; - this.annotation_type = data.annotation_type; + // this.annotationType = data.annotationType; checkNumberOfPoints(this.shapeType, this.points); } @@ -1472,7 +1476,7 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POINTS; - this.annotation_type = data.annotation_type; + // this.annotationType = data.annotationType; checkNumberOfPoints(this.shapeType, this.points); } @@ -1617,7 +1621,7 @@ super(data, clientID, color, injection); this.shapeType = ObjectShape.RECTANGLE; this.pinned = false; - this.annotation_type = AnnotationType.MANUAL; + // this.annotationType = AnnotationType.MANUAL; for (const shape of Object.values(this.shapes)) { checkNumberOfPoints(this.shapeType, shape.points); } @@ -2031,7 +2035,7 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POLYGON; - this.annotation_type = AnnotationType.MANUAL; + // this.annotationType = AnnotationType.MANUAL; for (const shape of Object.values(this.shapes)) { checkNumberOfPoints(this.shapeType, shape.points); } @@ -2042,7 +2046,7 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POLYLINE; - this.annotation_type = AnnotationType.MANUAL; + // this.annotationType = AnnotationType.MANUAL; for (const shape of Object.values(this.shapes)) { checkNumberOfPoints(this.shapeType, shape.points); } @@ -2053,7 +2057,7 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POINTS; - this.annotation_type = AnnotationType.MANUAL; + // this.annotationType = AnnotationType.MANUAL; for (const shape of Object.values(this.shapes)) { checkNumberOfPoints(this.shapeType, shape.points); } diff --git a/cvat-core/src/annotations-saver.js b/cvat-core/src/annotations-saver.js index d99e3370511e..b9850164a373 100644 --- a/cvat-core/src/annotations-saver.js +++ b/cvat-core/src/annotations-saver.js @@ -104,7 +104,7 @@ const keys = ['id', 'label_id', 'group', 'frame', 'occluded', 'z_order', 'points', 'type', 'shapes', - 'attributes', 'value', 'spec_id', 'annotation_type', 'outside']; + 'attributes', 'value', 'spec_id', 'annotationType', 'outside']; // Find created and updated objects for (const type of Object.keys(exported)) { diff --git a/cvat-core/src/enums.js b/cvat-core/src/enums.js index bf4ad217b99a..da221645d118 100644 --- a/cvat-core/src/enums.js +++ b/cvat-core/src/enums.js @@ -204,7 +204,7 @@ * @property {string} CHANGED_LOCK Changed lock * @property {string} CHANGED_COLOR Changed color * @property {string} CHANGED_HIDDEN Changed hidden - * @property {string} CHANGED_ANNOTATIONTYPE Changed annotation_type + * @property {string} CHANGED_ANNOTATION_TYPE Changed annotation type * @property {string} MERGED_OBJECTS Merged objects * @property {string} SPLITTED_TRACK Splitted track * @property {string} GROUPED_OBJECTS Grouped objects @@ -224,7 +224,7 @@ CHANGED_PINNED: 'Changed pinned', CHANGED_COLOR: 'Changed color', CHANGED_HIDDEN: 'Changed hidden', - CHANGED_ANNOTATIONTYPE: 'Changed annotation_type', + CHANGED_ANNOTATION_TYPE: 'Changed annotation type', MERGED_OBJECTS: 'Merged objects', SPLITTED_TRACK: 'Splitted track', GROUPED_OBJECTS: 'Grouped objects', diff --git a/cvat-core/src/object-state.js b/cvat-core/src/object-state.js index fb553452e2b2..331d646e7698 100644 --- a/cvat-core/src/object-state.js +++ b/cvat-core/src/object-state.js @@ -22,7 +22,7 @@ *
Necessary fields: objectType, shapeType, frame, updated, group *
Optional fields: keyframes, clientID, serverID *
Optional fields which can be set later: points, zOrder, outside, - * occluded, hidden, attributes, lock, label, color, keyframe, annotation_type + * occluded, hidden, attributes, lock, label, color, keyframe, annotationType */ constructor(serialized) { const data = { @@ -39,7 +39,7 @@ color: null, hidden: null, pinned: null, - annotation_type: null, + annotationType: null, keyframes: serialized.keyframes, group: serialized.group, updated: serialized.updated, @@ -69,7 +69,7 @@ this.lock = false; this.color = false; this.hidden = false; - this.annotation_type = false; + this.annotationType = false; return reset; }, @@ -111,18 +111,18 @@ */ get: () => data.shapeType, }, - annotation_type: { + annotationType: { /** - * @name annotation_type + * @name annotationType * @type {module:API.cvat.enums.AnnotationType} * @memberof module:API.cvat.classes.ObjectState * @readonly * @instance */ - get: () => data.annotation_type, - set: (annotation_type) => { - data.updateFlags.annotation_type = true; - data.annotation_type = annotation_type; + get: () => data.annotationType, + set: (annotationType) => { + data.updateFlags.annotationType = true; + data.annotationType = annotationType; }, }, clientID: { @@ -359,7 +359,7 @@ this.label = serialized.label; this.lock = serialized.lock; - this.annotation_type = serialized.annotation_type; + this.annotationType = serialized.annotationType; if (typeof (serialized.zOrder) === 'number') { this.zOrder = serialized.zOrder; diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx index 28cb0e032bea..3a59978ed79f 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx @@ -307,6 +307,7 @@ export default class CanvasWrapperComponent extends React.PureComponent { .filter((label: any) => label.id === activeLabelID)[0]; state.occluded = state.occluded || false; state.frame = frame; + state.annotationType = 'Manual'; const objectState = new cvat.classes.ObjectState(state); onCreateAnnotations(jobInstance, frame, [objectState]); }; @@ -482,10 +483,10 @@ export default class CanvasWrapperComponent extends React.PureComponent { const { state, points, - annotation_type, + // annotation_type, } = event.detail; state.points = points; - state.annotation_type = annotation_type; + state.annotation_type = 'Manual' onUpdateAnnotations([state]); }; From 9d6a09563d6dd73d29a7e9537ff5ba8b15fb9f57 Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Fri, 29 May 2020 17:20:07 +0530 Subject: [PATCH 09/18] updated CHANGELOG.md [1.0.0-beta.2], changed cvat-canvas file --- CHANGELOG.md | 2 + cvat-canvas/src/typescript/canvasModel.ts | 1 - cvat-canvas/src/typescript/canvasView.ts | 27 +---- cvat-canvas/src/typescript/drawHandler.ts | 16 --- cvat-core/src/annotations-collection.js | 1 + cvat-core/src/annotations-objects.js | 103 ++++++++---------- cvat-core/src/annotations-saver.js | 2 +- cvat-core/src/enums.js | 4 +- cvat-ui/src/actions/annotation-actions.ts | 1 + .../standard-workspace/canvas-wrapper.tsx | 3 +- 10 files changed, 57 insertions(+), 103 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2742d055756..1990f351f727 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Methods ``import`` and ``export`` to import/export raw annotations for Job and Task in ``cvat-core`` () - Versioning of client packages (``cvat-core``, ``cvat-canvas``, ``cvat-ui``). Initial versions are set to 1.0.0 () - Cuboids feature was migrated from old UI to new one. () +- Annotation type support for tags, shapes and tracks () +- Annotation type support for CVAT Dumper/Loader () ### Removed - Annotation convertation utils, currently supported natively via Datumaro framework (https://github.com/opencv/cvat/pull/1477) diff --git a/cvat-canvas/src/typescript/canvasModel.ts b/cvat-canvas/src/typescript/canvasModel.ts index c7513571a30b..bd93314bf3aa 100644 --- a/cvat-canvas/src/typescript/canvasModel.ts +++ b/cvat-canvas/src/typescript/canvasModel.ts @@ -60,7 +60,6 @@ export interface DrawData { numberOfPoints?: number; initialState?: any; crosshair?: boolean; - // annotation_type?: string; } export interface EditData { diff --git a/cvat-canvas/src/typescript/canvasView.ts b/cvat-canvas/src/typescript/canvasView.ts index f3a425e6654a..226a23f27f6f 100644 --- a/cvat-canvas/src/typescript/canvasView.ts +++ b/cvat-canvas/src/typescript/canvasView.ts @@ -40,7 +40,6 @@ import { Size, Configuration, } from './canvasModel'; -import { isNullOrUndefined } from 'util'; export interface CanvasView { html(): HTMLDivElement; @@ -117,14 +116,13 @@ export class CanvasViewImpl implements CanvasView, Listener { } private onEditDone(state: any, points: number[]): void { - if (state && points && annotation_type) { + if (state && points) { const event: CustomEvent = new CustomEvent('canvas.edited', { bubbles: false, cancelable: true, detail: { state, points, - // annotation_type, }, }); @@ -445,11 +443,9 @@ export class CanvasViewImpl implements CanvasView, Listener { } if (e.ctrlKey) { const { points } = state; - // const annotation_type = 'Manual'; self.onEditDone( state, points.slice(0, pointID * 2).concat(points.slice(pointID * 2 + 2)), - // annotation_type, ); } else if (e.shiftKey) { self.canvas.dispatchEvent(new CustomEvent('canvas.editstart', { @@ -1023,7 +1019,6 @@ export class CanvasViewImpl implements CanvasView, Listener { attributes: { ...state.attributes }, zOrder: state.zOrder, pinned: state.pinned, - // annotation_type: state.annotation_type, updated: state.updated, frame: state.frame, }; @@ -1380,7 +1375,6 @@ export class CanvasViewImpl implements CanvasView, Listener { id: state.clientID, }, })); - // const annotation_type = 'Manual'; this.onEditDone(state, points); } }); @@ -1429,7 +1423,6 @@ export class CanvasViewImpl implements CanvasView, Listener { + `${shape.attr('x') + shape.attr('width')},` + `${shape.attr('y') + shape.attr('height')}`, ).map((x: number): number => x - offset); - // const annotation_type = 'Manual'; this.drawnStates[state.clientID].points = points; this.canvas.dispatchEvent(new CustomEvent('canvas.resizeshape', { @@ -1522,14 +1515,14 @@ export class CanvasViewImpl implements CanvasView, Listener { private addText(state: any): SVG.Text { const { undefinedAttrValue } = this.configuration; - const { label, clientID, attributes, annotation_type } = state; + const { label, clientID, attributes, annotationType } = 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} (${annotation_type})`).style('text-transform', 'uppercase'); + block.tspan(`${label.name} ${clientID} (${annotationType})`).style('text-transform', 'uppercase'); for (const attrID of Object.keys(attributes)) { const value = attributes[attrID] === undefinedAttrValue ? '' : attributes[attrID]; @@ -1544,9 +1537,6 @@ export class CanvasViewImpl implements CanvasView, Listener { private addRect(points: number[], state: any): SVG.Rect { const [xtl, ytl, xbr, ybr] = points; - // if (typeof (state.annotation_type) === 'undefined') { - // state.annotation_type = 'Manual'; - // } const rect = this.adoptedContent.rect().size(xbr - xtl, ybr - ytl).attr({ clientID: state.clientID, 'color-rendering': 'optimizeQuality', @@ -1556,7 +1546,6 @@ export class CanvasViewImpl implements CanvasView, Listener { stroke: state.color, 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, 'data-z-order': state.zOrder, - // annotation_type: state.annotation_type, }).move(xtl, ytl) .addClass('cvat_canvas_shape'); @@ -1572,9 +1561,6 @@ export class CanvasViewImpl implements CanvasView, Listener { } private addPolygon(points: string, state: any): SVG.Polygon { - // if (typeof (state.annotation_type) === 'undefined') { - // state.annotation_type = 'Manual'; - // } const polygon = this.adoptedContent.polygon(points).attr({ clientID: state.clientID, 'color-rendering': 'optimizeQuality', @@ -1584,7 +1570,6 @@ export class CanvasViewImpl implements CanvasView, Listener { stroke: state.color, 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, 'data-z-order': state.zOrder, - // annotation_type: state.annotation_type, }).addClass('cvat_canvas_shape'); if (state.occluded) { @@ -1599,9 +1584,6 @@ export class CanvasViewImpl implements CanvasView, Listener { } private addPolyline(points: string, state: any): SVG.PolyLine { - // if (typeof (state.annotation_type) === 'undefined') { - // state.annotation_type = 'Manual'; - // } const polyline = this.adoptedContent.polyline(points).attr({ clientID: state.clientID, 'color-rendering': 'optimizeQuality', @@ -1611,7 +1593,6 @@ export class CanvasViewImpl implements CanvasView, Listener { stroke: state.color, 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, 'data-z-order': state.zOrder, - // annotation_type: state.annotation_type, }).addClass('cvat_canvas_shape'); if (state.occluded) { @@ -1674,14 +1655,12 @@ export class CanvasViewImpl implements CanvasView, Listener { } private addPoints(points: string, state: any): SVG.PolyLine { - // state.annotation_type = 'Manual'; const shape = this.adoptedContent.polyline(points).attr({ 'color-rendering': 'optimizeQuality', 'pointer-events': 'none', 'shape-rendering': 'geometricprecision', 'stroke-width': 0, fill: state.color, // to right fill property when call SVG.Shape::clone( - // annotation_type: state.annotation_type, }).style({ opacity: 0, }); diff --git a/cvat-canvas/src/typescript/drawHandler.ts b/cvat-canvas/src/typescript/drawHandler.ts index b9d5e17d54c8..8aa8b55101fb 100644 --- a/cvat-canvas/src/typescript/drawHandler.ts +++ b/cvat-canvas/src/typescript/drawHandler.ts @@ -267,11 +267,9 @@ export class DrawHandlerImpl implements DrawHandler { if (this.canceled) return; if ((xbr - xtl) * (ybr - ytl) >= consts.AREA_THRESHOLD) { - // this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType, points: [xtl, ytl, xbr, ybr], - // annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp); } }).on('drawupdate', (): void => { @@ -302,11 +300,9 @@ export class DrawHandlerImpl implements DrawHandler { this.cancel(); if ((xbr - xtl) * (ybr - ytl) >= consts.AREA_THRESHOLD) { - // this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType, points: [xtl, ytl, xbr, ybr], - // annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp); } } @@ -391,29 +387,23 @@ export class DrawHandlerImpl implements DrawHandler { if (shapeType === 'polygon' && ((box.xbr - box.xtl) * (box.ybr - box.ytl) >= consts.AREA_THRESHOLD) && points.length >= 3 * 2) { - // this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType, points, - // annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp); } else if (shapeType === 'polyline' && ((box.xbr - box.xtl) >= consts.SIZE_THRESHOLD || (box.ybr - box.ytl) >= consts.SIZE_THRESHOLD) && points.length >= 2 * 2) { - // this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType, points, - // annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp); } else if (shapeType === 'points' && (e.target as any).getAttribute('points') !== '0,0') { - // this.drawData.annotation_type = 'Manual'; this.onDrawDone({ shapeType, points, - // annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp); // TODO: think about correct constraign for cuboids } else if (shapeType === 'cuboid' @@ -481,7 +471,6 @@ export class DrawHandlerImpl implements DrawHandler { if (!e.detail.originalEvent.ctrlKey) { this.release(); - // this.drawData.annotation_type = 'Manual'; } this.onDrawDone({ @@ -492,7 +481,6 @@ export class DrawHandlerImpl implements DrawHandler { attributes: { ...this.drawData.initialState.attributes }, label: this.drawData.initialState.label, color: this.drawData.initialState.color, - // annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp, e.detail.originalEvent.ctrlKey); }); } @@ -526,7 +514,6 @@ export class DrawHandlerImpl implements DrawHandler { const [xtl, ytl, xbr, ybr] = this.getFinalRectCoordinates(bbox); if (!e.detail.originalEvent.ctrlKey) { this.release(); - // this.drawData.annotation_type = 'Manual'; } this.onDrawDone({ @@ -537,7 +524,6 @@ export class DrawHandlerImpl implements DrawHandler { attributes: { ...this.drawData.initialState.attributes }, label: this.drawData.initialState.label, color: this.drawData.initialState.color, - // annotation_type: this.drawData.annotation_type, }, Date.now() - this.startTimestamp, e.detail.originalEvent.ctrlKey); }); } @@ -650,7 +636,6 @@ export class DrawHandlerImpl implements DrawHandler { if (this.drawData.initialState) { const { offset } = this.geometry; if (this.drawData.shapeType === 'rectangle') { - // this.drawData.annotation_type = 'Manual'; const [xtl, ytl, xbr, ybr] = this.drawData.initialState.points .map((coord: number): number => coord + offset); @@ -679,7 +664,6 @@ export class DrawHandlerImpl implements DrawHandler { } else { if (this.drawData.shapeType === 'rectangle') { if (this.drawData.rectDrawingMethod === RectDrawingMethod.EXTREME_POINTS) { - // this.drawData.annotation_type = 'Manual'; // draw box by extreme clicking this.drawBoxBy4Points(); } else { diff --git a/cvat-core/src/annotations-collection.js b/cvat-core/src/annotations-collection.js index ce218ce3ae5b..79fecc2ed812 100644 --- a/cvat-core/src/annotations-collection.js +++ b/cvat-core/src/annotations-collection.js @@ -402,6 +402,7 @@ frame: Math.min.apply(null, Object.keys(keyframes).map((frame) => +frame)), shapes: Object.values(keyframes), group: 0, + annotation_type: objectStates[0].annotationType, label_id: label.id, attributes: Object.keys(objectStates[0].attributes) .reduce((accumulator, attrID) => { diff --git a/cvat-core/src/annotations-objects.js b/cvat-core/src/annotations-objects.js index fc3d5fd40632..6fc469502540 100644 --- a/cvat-core/src/annotations-objects.js +++ b/cvat-core/src/annotations-objects.js @@ -19,7 +19,6 @@ ObjectType, AttributeType, HistoryActions, - AnnotationType, } = require('./enums'); const { @@ -185,7 +184,7 @@ this.removed = false; this.lock = false; this.color = color; - this.annotationType = data.annotationType; + this.annotationType = data.annotation_type; this.updated = Date.now(); this.attributes = data.attributes.reduce((attributeAccumulator, attr) => { attributeAccumulator[attr.spec_id] = attr.value; @@ -416,7 +415,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.annotationType; + || updated.zOrder || updated.hidden || updated.lock || updated.pinned + || updated.annotationType; if (anyChanges) { this.updated = Date.now(); @@ -490,7 +490,6 @@ this.points = data.points; this.occluded = data.occluded; this.zOrder = data.z_order; - // this.annotationType = data.annotationType; } // Method is used to export data to the server @@ -542,7 +541,7 @@ updated: this.updated, pinned: this.pinned, frame, - annotationType:this.annotationType, + annotationType: this.annotationType, }; } @@ -591,20 +590,20 @@ this.zOrder = zOrder; } - _saveAnnotationType(annotationType, frame) { - const undoAnnotationType = this.annotationType; - const redoAnnotationType = annotationType; + // _saveAnnotationType(annotationType, frame) { + // const undoAnnotationType = this.annotationType; + // const redoAnnotationType = annotationType; - this.history.do(HistoryActions.CHANGED_ANNOTATION_TYPE, () => { - this.annotationType = undoAnnotationType; - this.updated = Date.now(); - }, () => { - this.annotationType = redoAnnotationType; - this.updated = Date.now(); - }, [this.clientID], frame); + // this.history.do(HistoryActions.CHANGED_ANNOTATION_TYPE, () => { + // this.annotationType = undoAnnotationType; + // this.updated = Date.now(); + // }, () => { + // this.annotationType = redoAnnotationType; + // this.updated = Date.now(); + // }, [this.clientID], frame); - this.annotationType = annotationType; - } + // this.annotationType = annotationType; + // } @@ -661,7 +660,7 @@ } if (updated.annotationType) { - this._saveAnnotationType(data.annotationType); + this._saveAnnotationType(data.annotationType, frame); } this.updateTimestamp(updated); @@ -681,7 +680,6 @@ zOrder: value.z_order, points: value.points, outside: value.outside, - // annotationType: value.annotationType, attributes: value.attributes.reduce((attributeAccumulator, attr) => { attributeAccumulator[attr.spec_id] = attr.value; return attributeAccumulator; @@ -926,7 +924,7 @@ outside: current.outside, occluded: current.occluded, attributes: {}, - annotationType: current.annotationType, + // annotationType: current.annotationType, }; } } @@ -989,7 +987,7 @@ outside: current.outside, occluded: current.occluded, attributes: {}, - annotationType: current.annotationType, + // annotationType: current.annotationType, }; this.shapes[frame] = redoShape; @@ -1012,7 +1010,7 @@ points: current.points, occluded: current.occluded, attributes: {}, - annotationType: current.annotationType, + // annotationType: current.annotationType, }; this.shapes[frame] = redoShape; @@ -1035,7 +1033,7 @@ points: current.points, outside: current.outside, attributes: {}, - annotationType: current.annotationType, + // annotationType: current.annotationType, }; this.shapes[frame] = redoShape; @@ -1058,7 +1056,7 @@ points: current.points, outside: current.outside, attributes: {}, - annotationType: current.annotationType, + // annotationType: current.annotationType, }; this.shapes[frame] = redoShape; @@ -1070,28 +1068,28 @@ ); } - _saveAnnotationType(frame, annotationType) { - const current = this.get(frame); - const wasKeyframe = frame in this.shapes; - const undoShape = wasKeyframe ? this.shapes[frame] : undefined; - const redoShape = wasKeyframe ? { ...this.shapes[frame], annotationType } : { - frame, - annotationType, - zOrder: current.zOrder, - points: current.points, - occluded: current.occluded, - outside: current.outside, - attributes: {}, - }; - - this.shapes[frame] = redoShape; - this._appendShapeActionToHistory( - HistoryActions.CHANGED_ANNOTATION_TYPE, - frame, - undoShape, - redoShape, - ); - } + // _saveAnnotationType(annotationType, frame) { + // const current = this.get(frame); + // const wasKeyframe = frame in this.shapes; + // const undoShape = wasKeyframe ? this.shapes[frame] : undefined; + // const redoShape = wasKeyframe ? { ...this.shapes[frame], annotationType } : { + // frame, + // annotationType, + // zOrder: current.zOrder, + // points: current.points, + // occluded: current.occluded, + // outside: current.outside, + // attributes: {}, + // }; + + // this.shapes[frame] = redoShape; + // this._appendShapeActionToHistory( + // HistoryActions.CHANGED_ANNOTATION_TYPE, + // frame, + // undoShape, + // redoShape, + // ); + // } _saveKeyframe(frame, keyframe) { const current = this.get(frame); @@ -1176,7 +1174,7 @@ } if (updated.annotationType) { - this._saveAnnotationType(frame, data.annotationType); + this._saveAnnotationType(data.annotationType, frame); } if (updated.keyframe) { @@ -1235,7 +1233,6 @@ class Tag extends Annotation { constructor(data, clientID, color, injection) { super(data, clientID, color, injection); - // this.annotationType = data.annotationType; } // Method is used to export data to the server @@ -1246,7 +1243,7 @@ frame: this.frame, label_id: this.label.id, group: this.group, - annotationType: this.annotationType, + annotation_type: this.annotationType, attributes: Object.keys(this.attributes).reduce((attributeAccumulator, attrId) => { attributeAccumulator.push({ spec_id: attrId, @@ -1328,7 +1325,6 @@ super(data, clientID, color, injection); this.shapeType = ObjectShape.RECTANGLE; this.pinned = false; - // this.annotationType = data.annotationType; checkNumberOfPoints(this.shapeType, this.points); } @@ -1355,7 +1351,6 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POLYGON; - // this.annotationType = data.annotationType; checkNumberOfPoints(this.shapeType, this.points); } @@ -1431,7 +1426,6 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POLYLINE; - // this.annotationType = data.annotationType; checkNumberOfPoints(this.shapeType, this.points); } @@ -1476,7 +1470,6 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POINTS; - // this.annotationType = data.annotationType; checkNumberOfPoints(this.shapeType, this.points); } @@ -1621,7 +1614,6 @@ super(data, clientID, color, injection); this.shapeType = ObjectShape.RECTANGLE; this.pinned = false; - // this.annotationType = AnnotationType.MANUAL; for (const shape of Object.values(this.shapes)) { checkNumberOfPoints(this.shapeType, shape.points); } @@ -2035,7 +2027,6 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POLYGON; - // this.annotationType = AnnotationType.MANUAL; for (const shape of Object.values(this.shapes)) { checkNumberOfPoints(this.shapeType, shape.points); } @@ -2046,7 +2037,6 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POLYLINE; - // this.annotationType = AnnotationType.MANUAL; for (const shape of Object.values(this.shapes)) { checkNumberOfPoints(this.shapeType, shape.points); } @@ -2057,7 +2047,6 @@ constructor(data, clientID, color, injection) { super(data, clientID, color, injection); this.shapeType = ObjectShape.POINTS; - // this.annotationType = AnnotationType.MANUAL; for (const shape of Object.values(this.shapes)) { checkNumberOfPoints(this.shapeType, shape.points); } diff --git a/cvat-core/src/annotations-saver.js b/cvat-core/src/annotations-saver.js index b9850164a373..d99e3370511e 100644 --- a/cvat-core/src/annotations-saver.js +++ b/cvat-core/src/annotations-saver.js @@ -104,7 +104,7 @@ const keys = ['id', 'label_id', 'group', 'frame', 'occluded', 'z_order', 'points', 'type', 'shapes', - 'attributes', 'value', 'spec_id', 'annotationType', 'outside']; + 'attributes', 'value', 'spec_id', 'annotation_type', 'outside']; // Find created and updated objects for (const type of Object.keys(exported)) { diff --git a/cvat-core/src/enums.js b/cvat-core/src/enums.js index da221645d118..b2b202895c79 100644 --- a/cvat-core/src/enums.js +++ b/cvat-core/src/enums.js @@ -104,7 +104,7 @@ CUBOID: 'cuboid', }); - /** + /** * Annotation type * @enum {string} * @name AnnotationType @@ -120,7 +120,7 @@ /** * Logger event types - * @enum {string} + * @enum {string} * @name LogType * @memberof module:API.cvat.enums * @property {string} loadJob Load job diff --git a/cvat-ui/src/actions/annotation-actions.ts b/cvat-ui/src/actions/annotation-actions.ts index b88b93123a0d..0155c7f4b9b8 100644 --- a/cvat-ui/src/actions/annotation-actions.ts +++ b/cvat-ui/src/actions/annotation-actions.ts @@ -490,6 +490,7 @@ export function propagateObjectAsync( label: objectState.label, zOrder: objectState.zOrder, frame: from, + annotationType: objectState.annotationType, }; await sessionInstance.logger.log( diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx index 3a59978ed79f..1c19e39a822c 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx @@ -483,10 +483,9 @@ export default class CanvasWrapperComponent extends React.PureComponent { const { state, points, - // annotation_type, } = event.detail; state.points = points; - state.annotation_type = 'Manual' + state.annotationType = 'Manual'; onUpdateAnnotations([state]); }; From 4bf3e482fe5afc9a9703ba5b179e03e316e5617d Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Tue, 2 Jun 2020 16:24:28 +0530 Subject: [PATCH 10/18] updated CHANGELOG.md [1.1.0-alpha] --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb28faee37ae..bf7b8e7a1fc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.1.0-alpha] - Unreleased ### Added - Throttling policy for unauthenticated users () +- Annotation type support for tags, shapes and tracks () +- Annotation type support for CVAT Dumper/Loader () ### Changed - @@ -81,8 +83,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Methods ``import`` and ``export`` to import/export raw annotations for Job and Task in ``cvat-core`` () - Versioning of client packages (``cvat-core``, ``cvat-canvas``, ``cvat-ui``). Initial versions are set to 1.0.0 () - Cuboids feature was migrated from old UI to new one. () -- Annotation type support for tags, shapes and tracks () -- Annotation type support for CVAT Dumper/Loader () ### Removed - Annotation convertation utils, currently supported natively via Datumaro framework (https://github.com/opencv/cvat/pull/1477) From ec69c8a53afaac98c319b1c6dcd0a6961b0f8c66 Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Tue, 2 Jun 2020 16:24:50 +0530 Subject: [PATCH 11/18] resolved conflicts --- cvat-core/src/annotations-objects.js | 46 ------------------- cvat/apps/dataset_manager/bindings.py | 6 ++- cvat/apps/dataset_manager/task.py | 3 ++ .../dataset_manager/tests/test_annotation.py | 1 + 4 files changed, 8 insertions(+), 48 deletions(-) diff --git a/cvat-core/src/annotations-objects.js b/cvat-core/src/annotations-objects.js index 540b996f7e2b..dc522bbc3d78 100644 --- a/cvat-core/src/annotations-objects.js +++ b/cvat-core/src/annotations-objects.js @@ -590,24 +590,6 @@ this.zOrder = zOrder; } - // _saveAnnotationType(annotationType, frame) { - // const undoAnnotationType = this.annotationType; - // const redoAnnotationType = annotationType; - - // this.history.do(HistoryActions.CHANGED_ANNOTATION_TYPE, () => { - // this.annotationType = undoAnnotationType; - // this.updated = Date.now(); - // }, () => { - // this.annotationType = redoAnnotationType; - // this.updated = Date.now(); - // }, [this.clientID], frame); - - // this.annotationType = annotationType; - // } - - - - save(frame, data) { if (frame !== this.frame) { throw new ScriptingError( @@ -924,7 +906,6 @@ outside: current.outside, occluded: current.occluded, attributes: {}, - // annotationType: current.annotationType, }; } } @@ -987,7 +968,6 @@ outside: current.outside, occluded: current.occluded, attributes: {}, - // annotationType: current.annotationType, }; this.shapes[frame] = redoShape; @@ -1010,7 +990,6 @@ points: current.points, occluded: current.occluded, attributes: {}, - // annotationType: current.annotationType, }; this.shapes[frame] = redoShape; @@ -1033,7 +1012,6 @@ points: current.points, outside: current.outside, attributes: {}, - // annotationType: current.annotationType, }; this.shapes[frame] = redoShape; @@ -1056,7 +1034,6 @@ points: current.points, outside: current.outside, attributes: {}, - // annotationType: current.annotationType, }; this.shapes[frame] = redoShape; @@ -1068,29 +1045,6 @@ ); } - // _saveAnnotationType(annotationType, frame) { - // const current = this.get(frame); - // const wasKeyframe = frame in this.shapes; - // const undoShape = wasKeyframe ? this.shapes[frame] : undefined; - // const redoShape = wasKeyframe ? { ...this.shapes[frame], annotationType } : { - // frame, - // annotationType, - // zOrder: current.zOrder, - // points: current.points, - // occluded: current.occluded, - // outside: current.outside, - // attributes: {}, - // }; - - // this.shapes[frame] = redoShape; - // this._appendShapeActionToHistory( - // HistoryActions.CHANGED_ANNOTATION_TYPE, - // frame, - // undoShape, - // redoShape, - // ); - // } - _saveKeyframe(frame, keyframe) { const current = this.get(frame); const wasKeyframe = frame in this.shapes; diff --git a/cvat/apps/dataset_manager/bindings.py b/cvat/apps/dataset_manager/bindings.py index 55f98accbb90..64642958a90f 100644 --- a/cvat/apps/dataset_manager/bindings.py +++ b/cvat/apps/dataset_manager/bindings.py @@ -19,13 +19,13 @@ 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, annotation_type, 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') + Tag = namedtuple('Tag', 'frame, label, attributes, annotation_type, group') Tag.__new__.__defaults__ = (0, ) Frame = namedtuple( 'Frame', 'idx, frame, name, width, height, labeled_shapes, tags') @@ -216,6 +216,7 @@ def _export_labeled_shape(self, shape): occluded=shape["occluded"], z_order=shape.get("z_order", 0), group=shape.get("group", 0), + annotation_type=shape["annotation_type"], attributes=self._export_attributes(shape["attributes"]), ) @@ -225,6 +226,7 @@ def _export_tag(self, tag): tag["frame"] * self._frame_step, label=self._get_label_name(tag["label_id"]), group=tag.get("group", 0), + annotation_type=tag["annotation_type"], attributes=self._export_attributes(tag["attributes"]), ) diff --git a/cvat/apps/dataset_manager/task.py b/cvat/apps/dataset_manager/task.py index 0d9985b724df..003ec72b814a 100644 --- a/cvat/apps/dataset_manager/task.py +++ b/cvat/apps/dataset_manager/task.py @@ -381,6 +381,7 @@ def _init_tags_from_db(self): 'frame', 'label_id', 'group', + 'annotation_type', 'labeledimageattributeval__spec_id', 'labeledimageattributeval__value', 'labeledimageattributeval__id', @@ -415,6 +416,7 @@ def _init_shapes_from_db(self): 'type', 'frame', 'group', + 'annotation_type', 'occluded', 'z_order', 'points', @@ -451,6 +453,7 @@ def _init_tracks_from_db(self): "frame", "label_id", "group", + "annotation_type", "labeledtrackattributeval__spec_id", "labeledtrackattributeval__value", "labeledtrackattributeval__id", diff --git a/cvat/apps/dataset_manager/tests/test_annotation.py b/cvat/apps/dataset_manager/tests/test_annotation.py index 2db3969906a5..a92c8cfe363b 100644 --- a/cvat/apps/dataset_manager/tests/test_annotation.py +++ b/cvat/apps/dataset_manager/tests/test_annotation.py @@ -13,6 +13,7 @@ def test_single_point_interpolation(self): "frame": 0, "label_id": 0, "group": None, + "annotation_type": "Manual", "attributes": [], "shapes": [ { From 904a2060859093a3a81e11617c69c1ae420b8c41 Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Sat, 20 Jun 2020 19:09:19 +0530 Subject: [PATCH 12/18] fixed unit test --- cvat/apps/dataset_manager/bindings.py | 7 +++++-- cvat/apps/dataset_manager/formats/cvat.py | 4 ++++ cvat/apps/dataset_manager/formats/mot.py | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cvat/apps/dataset_manager/bindings.py b/cvat/apps/dataset_manager/bindings.py index 64642958a90f..51adb3697636 100644 --- a/cvat/apps/dataset_manager/bindings.py +++ b/cvat/apps/dataset_manager/bindings.py @@ -22,8 +22,8 @@ class TaskData: 'LabeledShape', 'type, frame, label, points, occluded, attributes, annotation_type, 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) + 'TrackedShape', 'type, frame, points, occluded, outside, keyframe, attributes, annotation_type, group, z_order, label, track_id') + TrackedShape.__new__.__defaults__ = ('Manual', 0, 0, None, 0) Track = namedtuple('Track', 'label, group, shapes') Tag = namedtuple('Tag', 'frame, label, attributes, annotation_type, group') Tag.__new__.__defaults__ = (0, ) @@ -203,6 +203,7 @@ def _export_tracked_shape(self, shape): outside=shape.get("outside", False), keyframe=shape.get("keyframe", True), track_id=shape["track_id"], + annotation_type=shape.get("annotation_type", "Manual"), attributes=self._export_attributes(shape["attributes"]), ) @@ -597,6 +598,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), + annotation_type='Manual', attributes=[task_data.Attribute(name=n, value=str(v)) for n, v in ann.attributes.items()], )) @@ -605,6 +607,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), + annotation_type='Manual', attributes=[task_data.Attribute(name=n, value=str(v)) for n, v in ann.attributes.items()], )) diff --git a/cvat/apps/dataset_manager/formats/cvat.py b/cvat/apps/dataset_manager/formats/cvat.py index 517a5b444f24..838e3e1c65d0 100644 --- a/cvat/apps/dataset_manager/formats/cvat.py +++ b/cvat/apps/dataset_manager/formats/cvat.py @@ -306,6 +306,7 @@ def dump_track(idx, track): ("outside", str(int(shape.outside))), ("occluded", str(int(shape.occluded))), ("keyframe", str(int(shape.keyframe))), + ("annotation_type", str(shape.annotation_type)), ]) if shape.type == "rectangle": @@ -394,6 +395,7 @@ def dump_track(idx, track): z_order=shape.z_order, frame=shape.frame, attributes=shape.attributes, + annotation_type=shape.annotation_type, ), annotations.TrackedShape( type=shape.type, @@ -404,6 +406,7 @@ def dump_track(idx, track): z_order=shape.z_order, frame=shape.frame + annotations.frame_step, attributes=shape.attributes, + annotation_type=shape.annotation_type, ), ], )) @@ -461,6 +464,7 @@ def load(file_object, annotations): shape['frame'] = el.attrib['frame'] shape['outside'] = el.attrib['outside'] == "1" shape['keyframe'] = el.attrib['keyframe'] == "1" + shape['annotation_type'] = str(el.attrib.get('annotation_type', 'Manual')) else: shape['frame'] = frame_id shape['label'] = el.attrib['label'] diff --git a/cvat/apps/dataset_manager/formats/mot.py b/cvat/apps/dataset_manager/formats/mot.py index 4731284a75c4..cbb742e07a86 100644 --- a/cvat/apps/dataset_manager/formats/mot.py +++ b/cvat/apps/dataset_manager/formats/mot.py @@ -59,6 +59,7 @@ def _import(src_file, task_data): z_order=ann.z_order, frame=frame_id, attributes=[], + annotation_type='Manual', ) # build trajectories as lists of shapes in track dict From 30cda121c1d49d1ce8cbf05ccc7bf99e66248e51 Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Tue, 30 Jun 2020 16:23:56 +0530 Subject: [PATCH 13/18] *removed empty migration files *added field type for tracks --- cvat/apps/dataset_manager/bindings.py | 4 +- cvat/apps/dataset_manager/formats/cvat.py | 7 ++-- cvat/apps/dataset_manager/formats/mot.py | 2 +- ...5_0657_squashed_0029_auto_20200309_0733.py | 40 ------------------- .../migrations/0026_merge_20200417_1635.py | 31 ++++++++++++-- 5 files changed, 35 insertions(+), 49 deletions(-) delete mode 100644 cvat/apps/engine/migrations/0024_auto_20200225_0657_squashed_0029_auto_20200309_0733.py diff --git a/cvat/apps/dataset_manager/bindings.py b/cvat/apps/dataset_manager/bindings.py index 0a5979bff5b4..ab9eb9b3d338 100644 --- a/cvat/apps/dataset_manager/bindings.py +++ b/cvat/apps/dataset_manager/bindings.py @@ -26,7 +26,7 @@ class TaskData: TrackedShape = namedtuple( 'TrackedShape', 'type, frame, points, occluded, outside, keyframe, attributes, annotation_type, group, z_order, label, track_id') TrackedShape.__new__.__defaults__ = ('Manual', 0, 0, None, 0) - Track = namedtuple('Track', 'label, group, shapes') + Track = namedtuple('Track', 'label, group, annotation_type, shapes') Tag = namedtuple('Tag', 'frame, label, attributes, annotation_type, group') Tag.__new__.__defaults__ = (0, ) Frame = namedtuple( @@ -291,11 +291,13 @@ def tracks(self): tracked_shape["attributes"] += track["attributes"] tracked_shape["track_id"] = idx tracked_shape["group"] = track["group"] + tracked_shape["annotation_type"] = track["annotation_type"] tracked_shape["label_id"] = track["label_id"] yield TaskData.Track( label=self._get_label_name(track["label_id"]), group=track["group"], + annotation_type=track["annotation_type"], shapes=[self._export_tracked_shape(shape) for shape in tracked_shapes], ) diff --git a/cvat/apps/dataset_manager/formats/cvat.py b/cvat/apps/dataset_manager/formats/cvat.py index a60ced7167e8..ccb5a1582f22 100644 --- a/cvat/apps/dataset_manager/formats/cvat.py +++ b/cvat/apps/dataset_manager/formats/cvat.py @@ -294,6 +294,7 @@ def dump_track(idx, track): dump_data = OrderedDict([ ("id", str(track_id)), ("label", track.label), + ("annotation_type", track.annotation_type), ]) if track.group: @@ -306,7 +307,6 @@ def dump_track(idx, track): ("outside", str(int(shape.outside))), ("occluded", str(int(shape.occluded))), ("keyframe", str(int(shape.keyframe))), - ("annotation_type", str(shape.annotation_type)), ]) if shape.type == "rectangle": @@ -386,6 +386,7 @@ def dump_track(idx, track): dump_track(counter, annotations.Track( label=shape.label, group=shape.group, + annotation_type=shape.annotation_type, shapes=[annotations.TrackedShape( type=shape.type, points=shape.points, @@ -395,7 +396,6 @@ def dump_track(idx, track): z_order=shape.z_order, frame=shape.frame, attributes=shape.attributes, - annotation_type=shape.annotation_type, ), annotations.TrackedShape( type=shape.type, @@ -406,7 +406,6 @@ def dump_track(idx, track): z_order=shape.z_order, frame=shape.frame + annotations.frame_step, attributes=shape.attributes, - annotation_type=shape.annotation_type, ), ], )) @@ -433,6 +432,7 @@ def load(file_object, annotations): track = annotations.Track( label=el.attrib['label'], group=int(el.attrib.get('group_id', 0)), + annotation_type=el.attrib.get('annotation_type', 'Manual'), shapes=[], ) elif el.tag == 'image': @@ -464,7 +464,6 @@ def load(file_object, annotations): shape['frame'] = el.attrib['frame'] shape['outside'] = el.attrib['outside'] == "1" shape['keyframe'] = el.attrib['keyframe'] == "1" - shape['annotation_type'] = str(el.attrib.get('annotation_type', 'Manual')) else: shape['frame'] = frame_id shape['label'] = el.attrib['label'] diff --git a/cvat/apps/dataset_manager/formats/mot.py b/cvat/apps/dataset_manager/formats/mot.py index cd838717abfc..60e1ea40f57a 100644 --- a/cvat/apps/dataset_manager/formats/mot.py +++ b/cvat/apps/dataset_manager/formats/mot.py @@ -62,7 +62,7 @@ def _import(src_file, task_data): # 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(): diff --git a/cvat/apps/engine/migrations/0024_auto_20200225_0657_squashed_0029_auto_20200309_0733.py b/cvat/apps/engine/migrations/0024_auto_20200225_0657_squashed_0029_auto_20200309_0733.py deleted file mode 100644 index 741334f69087..000000000000 --- a/cvat/apps/engine/migrations/0024_auto_20200225_0657_squashed_0029_auto_20200309_0733.py +++ /dev/null @@ -1,40 +0,0 @@ -# Generated by Django 2.2.10 on 2020-03-22 19:38 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - replaces = [('engine', '0024_auto_20200225_0657'), ('engine', '0025_auto_20200306_0503'), ('engine', '0026_auto_20200306_0701'), ('engine', '0027_auto_20200306_1029'), ('engine', '0028_auto_20200309_0547'), ('engine', '0029_auto_20200309_0733')] - - dependencies = [ - ('engine', '0023_auto_20200113_1323'), - ] - - operations = [ - migrations.AddField( - model_name='labeledshape', - name='annotation_type', - field=models.CharField(choices=[('Auto', 'AUTO'), ('Manual', 'MANUAL')], default='Manual', max_length=16, null=True), - ), - migrations.AlterField( - model_name='labeledshape', - name='type', - field=models.CharField(choices=[('rectangle', 'RECTANGLE'), ('polygon', 'POLYGON'), ('polyline', 'POLYLINE'), ('points', 'POINTS'), ('cuboid', 'CUBOID')], max_length=16), - ), - migrations.AlterField( - model_name='trackedshape', - name='type', - field=models.CharField(choices=[('rectangle', 'RECTANGLE'), ('polygon', 'POLYGON'), ('polyline', 'POLYLINE'), ('points', 'POINTS'), ('cuboid', 'CUBOID')], max_length=16), - ), - migrations.AddField( - model_name='labeledimage', - name='annotation_type', - field=models.CharField(choices=[('Auto', 'AUTO'), ('Manual', 'MANUAL')], default='Manual', max_length=16, null=True), - ), - migrations.AddField( - model_name='labeledtrack', - name='annotation_type', - field=models.CharField(choices=[('Auto', 'AUTO'), ('Manual', 'MANUAL')], default='Manual', max_length=16, null=True), - ), - ] diff --git a/cvat/apps/engine/migrations/0026_merge_20200417_1635.py b/cvat/apps/engine/migrations/0026_merge_20200417_1635.py index 886980c9b477..25104cf9de3a 100644 --- a/cvat/apps/engine/migrations/0026_merge_20200417_1635.py +++ b/cvat/apps/engine/migrations/0026_merge_20200417_1635.py @@ -1,14 +1,39 @@ -# Generated by Django 2.2.10 on 2020-04-17 16:35 +# Generated by Django 2.2.10 on 2020-03-22 19:38 -from django.db import migrations +from django.db import migrations, models class Migration(migrations.Migration): + dependencies = [ - ('engine', '0024_auto_20200225_0657_squashed_0029_auto_20200309_0733'), ('engine', '0025_auto_20200324_1222'), ] operations = [ + migrations.AddField( + model_name='labeledshape', + name='annotation_type', + field=models.CharField(choices=[('Auto', 'AUTO'), ('Manual', 'MANUAL')], default='Manual', max_length=16, null=True), + ), + migrations.AlterField( + model_name='labeledshape', + name='type', + field=models.CharField(choices=[('rectangle', 'RECTANGLE'), ('polygon', 'POLYGON'), ('polyline', 'POLYLINE'), ('points', 'POINTS'), ('cuboid', 'CUBOID')], max_length=16), + ), + migrations.AlterField( + model_name='trackedshape', + name='type', + field=models.CharField(choices=[('rectangle', 'RECTANGLE'), ('polygon', 'POLYGON'), ('polyline', 'POLYLINE'), ('points', 'POINTS'), ('cuboid', 'CUBOID')], max_length=16), + ), + migrations.AddField( + model_name='labeledimage', + name='annotation_type', + field=models.CharField(choices=[('Auto', 'AUTO'), ('Manual', 'MANUAL')], default='Manual', max_length=16, null=True), + ), + migrations.AddField( + model_name='labeledtrack', + name='annotation_type', + field=models.CharField(choices=[('Auto', 'AUTO'), ('Manual', 'MANUAL')], default='Manual', max_length=16, null=True), + ), ] From 3695a5db5113e3af1f44c617a25e65770560facd Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Tue, 30 Jun 2020 16:32:22 +0530 Subject: [PATCH 14/18] unit test fix --- cvat/apps/dataset_manager/formats/mot.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cvat/apps/dataset_manager/formats/mot.py b/cvat/apps/dataset_manager/formats/mot.py index 91cd1c78e923..f5c016b2b616 100644 --- a/cvat/apps/dataset_manager/formats/mot.py +++ b/cvat/apps/dataset_manager/formats/mot.py @@ -55,6 +55,7 @@ def _import(src_file, task_data): group=0, frame=frame_number, attributes=[], + annotation_type='Manual', )) continue From cccecb01f4a046524d3d86ba025d61bc5b52bcd2 Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Sat, 18 Jul 2020 16:08:25 +0530 Subject: [PATCH 15/18] minor changes --- CHANGELOG.md | 8 +- cvat-canvas/src/typescript/canvasView.ts | 6 +- cvat-core/src/annotations-collection.js | 6 +- cvat-core/src/annotations-objects.js | 48 ++++++------ cvat-core/src/annotations-saver.js | 2 +- cvat-core/src/api.js | 4 +- cvat-core/src/enums.js | 18 ++--- cvat-core/src/object-state.js | 22 +++--- cvat-ui/src/actions/annotation-actions.ts | 2 +- .../standard-workspace/canvas-wrapper.tsx | 4 +- cvat/apps/dataset_manager/bindings.py | 24 +++--- cvat/apps/dataset_manager/formats/cvat.py | 14 ++-- cvat/apps/dataset_manager/formats/mot.py | 6 +- cvat/apps/dataset_manager/task.py | 6 +- .../dataset_manager/tests/_test_formats.py | 12 +-- .../dataset_manager/tests/test_annotation.py | 8 +- ...417_1635.py => 0026_auto_20200716_1934.py} | 27 ++++--- cvat/apps/engine/models.py | 8 +- cvat/apps/engine/serializers.py | 2 +- cvat/apps/engine/tests/_test_rest_api.py | 78 +++++++++---------- cvat/apps/tf_annotation/views.py | 2 +- 21 files changed, 153 insertions(+), 154 deletions(-) rename cvat/apps/engine/migrations/{0026_merge_20200417_1635.py => 0026_auto_20200716_1934.py} (64%) diff --git a/CHANGELOG.md b/CHANGELOG.md index b54ab78d1cff..e50e2f2603a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,8 +61,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [Datumaro] Added `convert` command to convert datasets directly () - [Datumaro] Added an option to specify image extension when exporting datasets () - [Datumaro] Added image copying when exporting datasets, if possible () -- Annotation type support for tags, shapes and tracks () -- Annotation type support for CVAT Dumper/Loader () +- Source type support for tags, shapes and tracks () +- Source type support for CVAT Dumper/Loader () ### Changed - Removed information about e-mail from the basic user information () @@ -472,8 +472,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.6.1] - 2020-04-14 ### Added - Annotation type to determine whether a drawn shape is auto annotated using Tensorflow Object detection API or manually annotated by the user -- Annotation_type field support for cvat dumper/loader -- Annotation_type field support for tags +- source field support for cvat dumper/loader +- source field support for tags ## Template ``` diff --git a/cvat-canvas/src/typescript/canvasView.ts b/cvat-canvas/src/typescript/canvasView.ts index 5e81fb5854a8..7194b0da767d 100644 --- a/cvat-canvas/src/typescript/canvasView.ts +++ b/cvat-canvas/src/typescript/canvasView.ts @@ -1732,14 +1732,14 @@ export class CanvasViewImpl implements CanvasView, Listener { private addText(state: any): SVG.Text { const { undefinedAttrValue } = this.configuration; - const { label, clientID, attributes, annotationType } = 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} (${annotationType})`).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]; @@ -1877,7 +1877,7 @@ export class CanvasViewImpl implements CanvasView, Listener { 'pointer-events': 'none', 'shape-rendering': 'geometricprecision', 'stroke-width': 0, - fill: state.color, // to right fill property when call SVG.Shape::clone( + fill: state.color, // to right fill property when call SVG.Shape::clone() }).style({ opacity: 0, }); diff --git a/cvat-core/src/annotations-collection.js b/cvat-core/src/annotations-collection.js index 518c5c99b246..ed338f6b37bd 100644 --- a/cvat-core/src/annotations-collection.js +++ b/cvat-core/src/annotations-collection.js @@ -402,7 +402,7 @@ frame: Math.min.apply(null, Object.keys(keyframes).map((frame) => +frame)), shapes: Object.values(keyframes), group: 0, - annotation_type: objectStates[0].annotationType, + source: objectStates[0].source, label_id: label.id, attributes: Object.keys(objectStates[0].attributes) .reduce((accumulator, attrID) => { @@ -764,7 +764,7 @@ points: [...state.points], type: state.shapeType, z_order: state.zOrder, - annotation_type: state.annotationType, + source: state.source, }); } else if (state.objectType === 'track') { constructed.tracks.push({ @@ -772,7 +772,7 @@ .filter((attr) => !labelAttributes[attr.spec_id].mutable), frame: state.frame, group: 0, - annotation_type: state.annotationType, + source: state.source, label_id: state.label.id, shapes: [{ attributes: attributes diff --git a/cvat-core/src/annotations-objects.js b/cvat-core/src/annotations-objects.js index a425ba79edcb..de02f8de6a65 100644 --- a/cvat-core/src/annotations-objects.js +++ b/cvat-core/src/annotations-objects.js @@ -183,7 +183,7 @@ this.removed = false; this.lock = false; this.color = color; - this.annotationType = data.annotation_type; + this.source = data.source; this.updated = Date.now(); this.attributes = data.attributes.reduce((attributeAccumulator, attr) => { attributeAccumulator[attr.spec_id] = attr.value; @@ -296,19 +296,19 @@ }, [this.clientID], frame); } - _saveAnnotationType(annotationType, frame) { - const undoAnnotationType = this.annotationType; - const redoAnnotationType = annotationType; + _saveSource(source, frame) { + const undoSource = this.source; + const redoSource = source; - this.history.do(HistoryActions.CHANGED_ANNOTATION_TYPE, () => { - this.annotationType = undoAnnotationType; + this.history.do(HistoryActions.CHANGED_SOURCE, () => { + this.source = undoSource; this.updated = Date.now(); }, () => { - this.annotationType = redoAnnotationType; + this.source = redoSource; this.updated = Date.now(); }, [this.clientID], frame); - this.annotationType = annotationType; + this.source = source; } _validateStateBeforeSave(frame, data, updated) { @@ -397,8 +397,8 @@ } } - if (updated.annotationType) { - checkObjectType('annotationType', data.annotationType, 'string', null); + if (updated.source) { + checkObjectType('source', data.source, 'string', null); } return fittedPoints; @@ -417,7 +417,7 @@ const anyChanges = updated.label || updated.attributes || updated.points || updated.outside || updated.occluded || updated.keyframe || updated.zOrder || updated.hidden || updated.lock || updated.pinned - || updated.annotationType; + || updated.source; if (anyChanges) { this.updated = Date.now(); @@ -513,7 +513,7 @@ frame: this.frame, label_id: this.label.id, group: this.group, - annotation_type: this.annotationType, + source: this.source, }; } @@ -542,7 +542,7 @@ updated: this.updated, pinned: this.pinned, frame, - annotationType: this.annotationType, + source: this.source, }; } @@ -642,8 +642,8 @@ this._saveHidden(data.hidden, frame); } - if (updated.annotationType) { - this._saveAnnotationType(data.annotationType, frame); + if (updated.source) { + this._saveSource(data.source, frame); } this.updateTimestamp(updated); @@ -686,7 +686,7 @@ frame: this.frame, label_id: this.label.id, group: this.group, - annotation_type: this.annotationType, + source: this.source, attributes: Object.keys(this.attributes).reduce((attributeAccumulator, attrId) => { if (!labelAttributes[attrId].mutable) { attributeAccumulator.push({ @@ -754,7 +754,7 @@ last, }, frame, - annotationType: this.annotationType, + source: this.source, }; } @@ -1063,7 +1063,7 @@ outside: current.outside, occluded: current.occluded, attributes: {}, - annotationType: current.annotationType, + source: current.source, } : undefined; if (redoShape) { @@ -1128,8 +1128,8 @@ this._saveAttributes(data.attributes, frame); } - if (updated.annotationType) { - this._saveAnnotationType(data.annotationType, frame); + if (updated.source) { + this._saveSource(data.source, frame); } if (updated.keyframe) { @@ -1198,7 +1198,7 @@ frame: this.frame, label_id: this.label.id, group: this.group, - annotation_type: this.annotationType, + source: this.source, attributes: Object.keys(this.attributes).reduce((attributeAccumulator, attrId) => { attributeAccumulator.push({ spec_id: attrId, @@ -1229,7 +1229,7 @@ color: this.color, updated: this.updated, frame, - annotationType: this.annotationType, + source: this.source, }; } @@ -1264,8 +1264,8 @@ this._saveColor(data.color, frame); } - if (updated.annotationType) { - this._saveAnnotationType(data.annotationType, frame); + if (updated.source) { + this._saveSource(data.source, frame); } this.updateTimestamp(updated); diff --git a/cvat-core/src/annotations-saver.js b/cvat-core/src/annotations-saver.js index d99e3370511e..779db776c0a5 100644 --- a/cvat-core/src/annotations-saver.js +++ b/cvat-core/src/annotations-saver.js @@ -104,7 +104,7 @@ const keys = ['id', 'label_id', 'group', 'frame', 'occluded', 'z_order', 'points', 'type', 'shapes', - 'attributes', 'value', 'spec_id', 'annotation_type', 'outside']; + 'attributes', 'value', 'spec_id', 'source', 'outside']; // Find created and updated objects for (const type of Object.keys(exported)) { diff --git a/cvat-core/src/api.js b/cvat-core/src/api.js index a2f7dfaa0e93..df6622f57610 100644 --- a/cvat-core/src/api.js +++ b/cvat-core/src/api.js @@ -31,7 +31,7 @@ function build() { LogType, HistoryActions, colors, - AnnotationType, + source, } = require('./enums'); const { @@ -532,7 +532,7 @@ function build() { LogType, HistoryActions, colors, - AnnotationType, + source, }, /** * Namespace is used for access to exceptions diff --git a/cvat-core/src/enums.js b/cvat-core/src/enums.js index 79a820f0ac87..894760cfee32 100644 --- a/cvat-core/src/enums.js +++ b/cvat-core/src/enums.js @@ -107,15 +107,15 @@ /** * Annotation type * @enum {string} - * @name AnnotationType + * @name source * @memberof module:API.cvat.enums - * @property {string} MANUAL 'Manual' - * @property {string} AUTO 'Auto' + * @property {string} MANUAL 'manual' + * @property {string} AUTO 'auto' * @readonly */ - const AnnotationType = Object.freeze({ - MANUAL:'Manual', - AUTO:'Auto', + const source = Object.freeze({ + MANUAL:'manual', + AUTO:'auto', }); /** @@ -204,7 +204,7 @@ * @property {string} CHANGED_LOCK Changed lock * @property {string} CHANGED_COLOR Changed color * @property {string} CHANGED_HIDDEN Changed hidden - * @property {string} CHANGED_ANNOTATION_TYPE Changed annotation type + * @property {string} CHANGED_SOURCE Changed source * @property {string} MERGED_OBJECTS Merged objects * @property {string} SPLITTED_TRACK Splitted track * @property {string} GROUPED_OBJECTS Grouped objects @@ -224,7 +224,7 @@ CHANGED_PINNED: 'Changed pinned', CHANGED_COLOR: 'Changed color', CHANGED_HIDDEN: 'Changed hidden', - CHANGED_ANNOTATION_TYPE: 'Changed annotation type', + CHANGED_SOURCE: 'Changed source', MERGED_OBJECTS: 'Merged objects', SPLITTED_TRACK: 'Splitted track', GROUPED_OBJECTS: 'Grouped objects', @@ -257,6 +257,6 @@ LogType, HistoryActions, colors, - AnnotationType, + source, }; })(); diff --git a/cvat-core/src/object-state.js b/cvat-core/src/object-state.js index 331d646e7698..1b3e4c483a03 100644 --- a/cvat-core/src/object-state.js +++ b/cvat-core/src/object-state.js @@ -22,7 +22,7 @@ *
Necessary fields: objectType, shapeType, frame, updated, group *
Optional fields: keyframes, clientID, serverID *
Optional fields which can be set later: points, zOrder, outside, - * occluded, hidden, attributes, lock, label, color, keyframe, annotationType + * occluded, hidden, attributes, lock, label, color, keyframe, source */ constructor(serialized) { const data = { @@ -39,7 +39,7 @@ color: null, hidden: null, pinned: null, - annotationType: null, + source: null, keyframes: serialized.keyframes, group: serialized.group, updated: serialized.updated, @@ -69,7 +69,7 @@ this.lock = false; this.color = false; this.hidden = false; - this.annotationType = false; + this.source = false; return reset; }, @@ -111,18 +111,18 @@ */ get: () => data.shapeType, }, - annotationType: { + source: { /** - * @name annotationType - * @type {module:API.cvat.enums.AnnotationType} + * @name source + * @type {module:API.cvat.enums.source} * @memberof module:API.cvat.classes.ObjectState * @readonly * @instance */ - get: () => data.annotationType, - set: (annotationType) => { - data.updateFlags.annotationType = true; - data.annotationType = annotationType; + get: () => data.source, + set: (source) => { + data.updateFlags.source = true; + data.source = source; }, }, clientID: { @@ -359,7 +359,7 @@ this.label = serialized.label; this.lock = serialized.lock; - this.annotationType = serialized.annotationType; + this.source = serialized.source; if (typeof (serialized.zOrder) === 'number') { this.zOrder = serialized.zOrder; diff --git a/cvat-ui/src/actions/annotation-actions.ts b/cvat-ui/src/actions/annotation-actions.ts index 5af74726c17f..5aa6c4575023 100644 --- a/cvat-ui/src/actions/annotation-actions.ts +++ b/cvat-ui/src/actions/annotation-actions.ts @@ -485,7 +485,7 @@ export function propagateObjectAsync( label: objectState.label, zOrder: objectState.zOrder, frame: from, - annotationType: objectState.annotationType, + source: objectState.source, }; await sessionInstance.logger.log( diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx index 0da35c1eb549..4824a4428119 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx @@ -324,7 +324,7 @@ export default class CanvasWrapperComponent extends React.PureComponent { .filter((label: any) => label.id === activeLabelID)[0]; state.occluded = state.occluded || false; state.frame = frame; - state.annotationType = 'Manual'; + state.source = 'manual'; const objectState = new cvat.classes.ObjectState(state); onCreateAnnotations(jobInstance, frame, [objectState]); }; @@ -501,7 +501,7 @@ export default class CanvasWrapperComponent extends React.PureComponent { points, } = event.detail; state.points = points; - state.annotationType = 'Manual'; + state.source = 'manual'; onUpdateAnnotations([state]); }; diff --git a/cvat/apps/dataset_manager/bindings.py b/cvat/apps/dataset_manager/bindings.py index 26d5cfac1107..7e20fc33f7e7 100644 --- a/cvat/apps/dataset_manager/bindings.py +++ b/cvat/apps/dataset_manager/bindings.py @@ -21,13 +21,13 @@ class TaskData: Attribute = namedtuple('Attribute', 'name, value') LabeledShape = namedtuple( - 'LabeledShape', 'type, frame, label, points, occluded, attributes, annotation_type, 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, annotation_type, group, z_order, label, track_id') - TrackedShape.__new__.__defaults__ = ('Manual', 0, 0, None, 0) - Track = namedtuple('Track', 'label, group, annotation_type, shapes') - Tag = namedtuple('Tag', 'frame, label, attributes, annotation_type, 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,7 +217,7 @@ def _export_tracked_shape(self, shape): outside=shape.get("outside", False), keyframe=shape.get("keyframe", True), track_id=shape["track_id"], - annotation_type=shape.get("annotation_type", "Manual"), + source=shape.get("source", "manual"), attributes=self._export_attributes(shape["attributes"]), ) @@ -230,7 +230,7 @@ def _export_labeled_shape(self, shape): occluded=shape["occluded"], z_order=shape.get("z_order", 0), group=shape.get("group", 0), - annotation_type=shape["annotation_type"], + source=shape["source"], attributes=self._export_attributes(shape["attributes"]), ) @@ -239,7 +239,7 @@ def _export_tag(self, tag): frame=self.abs_frame_id(tag["frame"]), label=self._get_label_name(tag["label_id"]), group=tag.get("group", 0), - annotation_type=tag["annotation_type"], + source=tag["source"], attributes=self._export_attributes(tag["attributes"]), ) @@ -293,13 +293,13 @@ def tracks(self): tracked_shape["attributes"] += track["attributes"] tracked_shape["track_id"] = idx tracked_shape["group"] = track["group"] - tracked_shape["annotation_type"] = track["annotation_type"] + 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"], - annotation_type=track["annotation_type"], + source=track["source"], shapes=[self._export_tracked_shape(shape) for shape in tracked_shapes], ) @@ -655,7 +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), - annotation_type='Manual', + source='manual', attributes=[task_data.Attribute(name=n, value=str(v)) for n, v in ann.attributes.items()], )) @@ -664,7 +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), - annotation_type='Manual', + source='manual', attributes=[task_data.Attribute(name=n, value=str(v)) for n, v in ann.attributes.items()], )) diff --git a/cvat/apps/dataset_manager/formats/cvat.py b/cvat/apps/dataset_manager/formats/cvat.py index 1290f33e6f79..ae1257c27081 100644 --- a/cvat/apps/dataset_manager/formats/cvat.py +++ b/cvat/apps/dataset_manager/formats/cvat.py @@ -190,7 +190,7 @@ def dump_as_cvat_annotation(file_object, annotations): dump_data = OrderedDict([ ("label", shape.label), ("occluded", str(int(shape.occluded))), - ("annotation_type", shape.annotation_type), + ("source", shape.source), ]) if shape.type == "rectangle": @@ -270,7 +270,7 @@ def dump_as_cvat_annotation(file_object, annotations): for tag in frame_annotation.tags: tag_data = OrderedDict([ ("label", tag.label), - ("annotation_type", tag.annotation_type), + ("source", tag.source), ]) if tag.group: tag_data["group_id"] = str(tag.group) @@ -296,7 +296,7 @@ def dump_track(idx, track): dump_data = OrderedDict([ ("id", str(track_id)), ("label", track.label), - ("annotation_type", track.annotation_type), + ("source", track.source), ]) if track.group: @@ -388,7 +388,7 @@ def dump_track(idx, track): dump_track(counter, annotations.Track( label=shape.label, group=shape.group, - annotation_type=shape.annotation_type, + source=shape.source, shapes=[annotations.TrackedShape( type=shape.type, points=shape.points, @@ -434,7 +434,7 @@ def load(file_object, annotations): track = annotations.Track( label=el.attrib['label'], group=int(el.attrib.get('group_id', 0)), - annotation_type=el.attrib.get('annotation_type', 'Manual'), + source=el.attrib.get('source', 'manual'), shapes=[], ) elif el.tag == 'image': @@ -453,7 +453,7 @@ def load(file_object, annotations): 'label': el.attrib['label'], 'group': int(el.attrib.get('group_id', 0)), 'attributes': attributes, - 'annotation_type': str(el.attrib.get('annotation_type', 'Manual')) + 'source': str(el.attrib.get('source', 'manual')) } elif ev == 'end': if el.tag == 'attribute' and attributes is not None: @@ -470,7 +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['annotation_type'] = str(el.attrib.get('annotation_type', 'Manual')) + shape['source'] = str(el.attrib.get('source', 'manual')) shape['type'] = 'rectangle' if el.tag == 'box' else el.tag shape['occluded'] = el.attrib['occluded'] == '1' diff --git a/cvat/apps/dataset_manager/formats/mot.py b/cvat/apps/dataset_manager/formats/mot.py index d28485c005f1..b854ddb2b8bb 100644 --- a/cvat/apps/dataset_manager/formats/mot.py +++ b/cvat/apps/dataset_manager/formats/mot.py @@ -54,7 +54,7 @@ def _import(src_file, task_data): group=0, frame=frame_number, attributes=[], - annotation_type='Manual', + source='manual', )) continue @@ -67,13 +67,13 @@ def _import(src_file, task_data): z_order=ann.z_order, frame=frame_number, attributes=[], - annotation_type='Manual', + 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, 'Manual', []) + label_cat.items[ann.label].name, 0, 'manual', []) tracks[track_id].shapes.append(shape) for track in tracks.values(): diff --git a/cvat/apps/dataset_manager/task.py b/cvat/apps/dataset_manager/task.py index 003ec72b814a..f2c40dfd0a17 100644 --- a/cvat/apps/dataset_manager/task.py +++ b/cvat/apps/dataset_manager/task.py @@ -381,7 +381,7 @@ def _init_tags_from_db(self): 'frame', 'label_id', 'group', - 'annotation_type', + 'source', 'labeledimageattributeval__spec_id', 'labeledimageattributeval__value', 'labeledimageattributeval__id', @@ -416,7 +416,7 @@ def _init_shapes_from_db(self): 'type', 'frame', 'group', - 'annotation_type', + 'source', 'occluded', 'z_order', 'points', @@ -453,7 +453,7 @@ def _init_tracks_from_db(self): "frame", "label_id", "group", - "annotation_type", + "source", "labeledtrackattributeval__spec_id", "labeledtrackattributeval__value", "labeledtrackattributeval__id", diff --git a/cvat/apps/dataset_manager/tests/_test_formats.py b/cvat/apps/dataset_manager/tests/_test_formats.py index 124966ce1330..3b4ea5487ae0 100644 --- a/cvat/apps/dataset_manager/tests/_test_formats.py +++ b/cvat/apps/dataset_manager/tests/_test_formats.py @@ -163,7 +163,7 @@ def _generate_annotations(self, task): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -182,7 +182,7 @@ def _generate_annotations(self, task): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", @@ -192,7 +192,7 @@ def _generate_annotations(self, task): "frame": 1, "label_id": task["labels"][0]["id"], "group": 1, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "points": [100, 300.222, 400, 500, 1, 3], "type": "points", @@ -202,7 +202,7 @@ def _generate_annotations(self, task): "frame": 1, "label_id": task["labels"][0]["id"], "group": 1, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "points": [2.0, 2.1, 400, 500, 1, 3], "type": "polyline", @@ -214,7 +214,7 @@ def _generate_annotations(self, task): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -249,7 +249,7 @@ def _generate_annotations(self, task): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "shapes": [ { diff --git a/cvat/apps/dataset_manager/tests/test_annotation.py b/cvat/apps/dataset_manager/tests/test_annotation.py index 93b6135574b2..580243a9cde3 100644 --- a/cvat/apps/dataset_manager/tests/test_annotation.py +++ b/cvat/apps/dataset_manager/tests/test_annotation.py @@ -13,7 +13,7 @@ def test_point_interpolation(self): "frame": 0, "label_id": 0, "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "shapes": [ { @@ -45,7 +45,7 @@ def test_polygon_interpolation(self): "label_id": 0, "group": None, "attributes": [], - "annotation_type": "Manual", + "source": "manual", "shapes": [ { "frame": 0, @@ -76,7 +76,7 @@ def test_bbox_interpolation(self): "label_id": 0, "group": None, "attributes": [], - "annotation_type": "Manual", + "source": "manual", "shapes": [ { "frame": 0, @@ -107,7 +107,7 @@ def test_line_interpolation(self): "label_id": 0, "group": None, "attributes": [], - "annotation_type": "Manual", + "source": "manual", "shapes": [ { "frame": 0, diff --git a/cvat/apps/engine/migrations/0026_merge_20200417_1635.py b/cvat/apps/engine/migrations/0026_auto_20200716_1934.py similarity index 64% rename from cvat/apps/engine/migrations/0026_merge_20200417_1635.py rename to cvat/apps/engine/migrations/0026_auto_20200716_1934.py index 25104cf9de3a..b2c1ea13dd61 100644 --- a/cvat/apps/engine/migrations/0026_merge_20200417_1635.py +++ b/cvat/apps/engine/migrations/0026_auto_20200716_1934.py @@ -1,20 +1,29 @@ -# Generated by Django 2.2.10 on 2020-03-22 19:38 +# Generated by Django 2.2.10 on 2020-07-16 19:34 from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('engine', '0025_auto_20200324_1222'), ] 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='annotation_type', - field=models.CharField(choices=[('Auto', 'AUTO'), ('Manual', 'MANUAL')], default='Manual', max_length=16, null=True), + 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), ), migrations.AlterField( model_name='labeledshape', @@ -26,14 +35,4 @@ class Migration(migrations.Migration): name='type', field=models.CharField(choices=[('rectangle', 'RECTANGLE'), ('polygon', 'POLYGON'), ('polyline', 'POLYLINE'), ('points', 'POINTS'), ('cuboid', 'CUBOID')], max_length=16), ), - migrations.AddField( - model_name='labeledimage', - name='annotation_type', - field=models.CharField(choices=[('Auto', 'AUTO'), ('Manual', 'MANUAL')], default='Manual', max_length=16, null=True), - ), - migrations.AddField( - model_name='labeledtrack', - name='annotation_type', - field=models.CharField(choices=[('Auto', 'AUTO'), ('Manual', 'MANUAL')], default='Manual', max_length=16, null=True), - ), ] diff --git a/cvat/apps/engine/models.py b/cvat/apps/engine/models.py index 92f7f2ff0b69..d4c46eb3e264 100644 --- a/cvat/apps/engine/models.py +++ b/cvat/apps/engine/models.py @@ -302,9 +302,9 @@ def choices(cls): def __str__(self): return self.value -class AnnotationType(str, Enum): - AUTO = 'Auto' - MANUAL = 'Manual' +class source(str, Enum): + AUTO = 'auto' + MANUAL = 'manual' @classmethod def choices(self): @@ -319,7 +319,7 @@ class Annotation(models.Model): label = models.ForeignKey(Label, on_delete=models.CASCADE) frame = models.PositiveIntegerField() group = models.PositiveIntegerField(null=True) - annotation_type = models.CharField(max_length=16, choices=AnnotationType.choices(), default="Manual", null=True) + source = models.CharField(max_length=16, choices=source.choices(), default="manual", null=True) class Meta: abstract = True diff --git a/cvat/apps/engine/serializers.py b/cvat/apps/engine/serializers.py index e7311a0f1195..90e24714c7d5 100644 --- a/cvat/apps/engine/serializers.py +++ b/cvat/apps/engine/serializers.py @@ -409,7 +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) - annotation_type = serializers.CharField(default = 'Manual') + source = serializers.CharField(default = 'manual') class LabeledImageSerializer(AnnotationSerializer): attributes = AttributeValSerializer(many=True, diff --git a/cvat/apps/engine/tests/_test_rest_api.py b/cvat/apps/engine/tests/_test_rest_api.py index fb78c4b962d5..73c8114185ee 100644 --- a/cvat/apps/engine/tests/_test_rest_api.py +++ b/cvat/apps/engine/tests/_test_rest_api.py @@ -2100,7 +2100,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [] } ], @@ -2109,7 +2109,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -2128,7 +2128,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", @@ -2140,7 +2140,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -2175,7 +2175,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "shapes": [ { @@ -2225,7 +2225,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [] } ], @@ -2234,7 +2234,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -2253,7 +2253,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", @@ -2265,7 +2265,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -2300,7 +2300,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "shapes": [ { @@ -2371,7 +2371,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": 11010101, "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], } ], @@ -2380,7 +2380,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [ { "spec_id": 32234234, @@ -2399,7 +2399,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": 1212121, "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", @@ -2411,7 +2411,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": 0, "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "shapes": [ { @@ -2445,7 +2445,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "shapes": [ { @@ -2589,7 +2589,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], } ], @@ -2598,7 +2598,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -2617,7 +2617,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", @@ -2629,7 +2629,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -2665,7 +2665,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "shapes": [ { @@ -2715,7 +2715,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], } ], @@ -2724,7 +2724,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -2743,7 +2743,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", @@ -2755,7 +2755,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -2790,7 +2790,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "shapes": [ { @@ -2861,7 +2861,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": 11010101, "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], } ], @@ -2870,7 +2870,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": task["labels"][0]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [ { "spec_id": 32234234, @@ -2889,7 +2889,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": 1212121, "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "points": [2.0, 2.1, 100, 300.222, 400, 500, 1, 3], "type": "polygon", @@ -2901,7 +2901,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 0, "label_id": 0, "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "shapes": [ { @@ -2935,7 +2935,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee, annotator): "frame": 1, "label_id": task["labels"][1]["id"], "group": None, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "shapes": [ { @@ -2971,7 +2971,7 @@ def _get_initial_annotation(annotation_format): "frame": 0, "label_id": task["labels"][0]["id"], "group": 0, - "annotation_type": "Manual", + "source": "manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -3024,7 +3024,7 @@ def _get_initial_annotation(annotation_format): "frame": 0, "label_id": task["labels"][1]["id"], "group": 0, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "shapes": [ { @@ -3058,7 +3058,7 @@ def _get_initial_annotation(annotation_format): "frame": 0, "label_id": task["labels"][0]["id"], "group": 0, - "annotation_type": "Manual", + "source": "manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -3078,7 +3078,7 @@ def _get_initial_annotation(annotation_format): "frame": 1, "label_id": task["labels"][1]["id"], "group": 0, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "points": [2.0, 2.1, 40, 50.7], "type": "rectangle", @@ -3089,7 +3089,7 @@ def _get_initial_annotation(annotation_format): "frame": 1, "label_id": task["labels"][1]["id"], "group": 0, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "points": [2.0, 2.1, 100, 30.22, 40, 77, 1, 3], "type": "polygon", @@ -3100,7 +3100,7 @@ def _get_initial_annotation(annotation_format): "frame": 2, "label_id": task["labels"][0]["id"], "group": 1, - "annotation_type": "Manual", + "source": "manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], @@ -3119,7 +3119,7 @@ def _get_initial_annotation(annotation_format): "frame": 2, "label_id": task["labels"][1]["id"], "group": 1, - "annotation_type": "Manual", + "source": "manual", "attributes": [], "points": [4, 7, 10, 30, 4, 5.55], "type": "polygon", @@ -3130,14 +3130,14 @@ def _get_initial_annotation(annotation_format): "frame": 2, "label_id": task["labels"][1]["id"], "group": 0, - "annotation_type": "Manual", + "source": "manual", "attributes": [], }] tags_with_attrs = [{ "frame": 1, "label_id": task["labels"][0]["id"], "group": 3, - "annotation_type": "Manual", + "source": "manual", "attributes": [ { "spec_id": task["labels"][0]["attributes"][0]["id"], diff --git a/cvat/apps/tf_annotation/views.py b/cvat/apps/tf_annotation/views.py index e54a21c7cfb9..e112860e5219 100644 --- a/cvat/apps/tf_annotation/views.py +++ b/cvat/apps/tf_annotation/views.py @@ -174,7 +174,7 @@ def convert_to_cvat_format(data): "group": None, "occluded": False, "attributes": [], - "annotation_type": "Auto", + "source": "auto", }) return result From 3513fe768cd6344e7c4e126347dac7fe770b541e Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Sun, 19 Jul 2020 21:57:11 +0530 Subject: [PATCH 16/18] included migrations --- ...20200716_1934.py => 0027_auto_20200719_1552.py} | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) rename cvat/apps/engine/migrations/{0026_auto_20200716_1934.py => 0027_auto_20200719_1552.py} (55%) diff --git a/cvat/apps/engine/migrations/0026_auto_20200716_1934.py b/cvat/apps/engine/migrations/0027_auto_20200719_1552.py similarity index 55% rename from cvat/apps/engine/migrations/0026_auto_20200716_1934.py rename to cvat/apps/engine/migrations/0027_auto_20200719_1552.py index b2c1ea13dd61..4ffffd6ac905 100644 --- a/cvat/apps/engine/migrations/0026_auto_20200716_1934.py +++ b/cvat/apps/engine/migrations/0027_auto_20200719_1552.py @@ -1,4 +1,4 @@ -# Generated by Django 2.2.10 on 2020-07-16 19:34 +# Generated by Django 2.2.10 on 2020-07-19 15:52 from django.db import migrations, models @@ -6,7 +6,7 @@ class Migration(migrations.Migration): dependencies = [ - ('engine', '0025_auto_20200324_1222'), + ('engine', '0026_auto_20200719_1511'), ] operations = [ @@ -25,14 +25,4 @@ class Migration(migrations.Migration): name='source', field=models.CharField(choices=[('auto', 'AUTO'), ('manual', 'MANUAL')], default='manual', max_length=16, null=True), ), - migrations.AlterField( - model_name='labeledshape', - name='type', - field=models.CharField(choices=[('rectangle', 'RECTANGLE'), ('polygon', 'POLYGON'), ('polyline', 'POLYLINE'), ('points', 'POINTS'), ('cuboid', 'CUBOID')], max_length=16), - ), - migrations.AlterField( - model_name='trackedshape', - name='type', - field=models.CharField(choices=[('rectangle', 'RECTANGLE'), ('polygon', 'POLYGON'), ('polyline', 'POLYLINE'), ('points', 'POINTS'), ('cuboid', 'CUBOID')], max_length=16), - ), ] From c3590a154ca4c3ef50475eee708ef344e6d9cfee Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Tue, 21 Jul 2020 01:28:27 +0530 Subject: [PATCH 17/18] updated CHANGELOG.md --- CHANGELOG.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e50e2f2603a6..39736394ab8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 () +- Source type support for CVAT Dumper/Loader () ### Changed - Smaller object details () @@ -61,8 +62,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [Datumaro] Added `convert` command to convert datasets directly () - [Datumaro] Added an option to specify image extension when exporting datasets () - [Datumaro] Added image copying when exporting datasets, if possible () -- Source type support for tags, shapes and tracks () -- Source type support for CVAT Dumper/Loader () ### Changed - Removed information about e-mail from the basic user information () From 562ea5f58e8f63c361861ec8e16c78d627c01670 Mon Sep 17 00:00:00 2001 From: Priya4607 Date: Fri, 24 Jul 2020 03:48:12 +0530 Subject: [PATCH 18/18] updated CHANGELOG.md --- CHANGELOG.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39736394ab8d..101f5a8483db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -468,12 +468,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Initial version -## [0.6.1] - 2020-04-14 -### Added -- Annotation type to determine whether a drawn shape is auto annotated using Tensorflow Object detection API or manually annotated by the user -- source field support for cvat dumper/loader -- source field support for tags - ## Template ``` ## [Unreleased]