Merge remote-tracking branch 'origin/release-0.3' into develop

main
Nikita Manovich 7 years ago
commit 641ad4bf57

@ -524,14 +524,15 @@ function uploadAnnotationRequest() {
$.ajax({
url: '/get/task/' + window.cvat.dashboard.taskID,
success: function(data) {
let annotationParser = new AnnotationParser({
let annotationParser = new AnnotationParser(
{
start: 0,
stop: data.size,
image_meta_data: data.image_meta_data,
flipped: data.flipped
},
new LabelsInfo(data.spec),
new ConstIdGenerator(-1),
new ConstIdGenerator(-1)
);
let asyncParse = function() {
@ -559,7 +560,7 @@ function uploadAnnotationRequest() {
overlay.remove();
},
});
}
};
let asyncSaveChunk = function(start) {
const CHUNK_SIZE = 100000;

@ -472,6 +472,7 @@ class _Annotation:
group_id=box.group_id,
boxes=[box0, box1],
attributes=box.attributes,
client_id=box.client_id,
)
paths.append(path)
@ -491,6 +492,7 @@ class _Annotation:
stop_frame=shape.frame + 1,
group_id=shape.group_id,
shapes=[shape0, shape1],
client_id=shape.client_id,
attributes=shape.attributes,
)
paths.append(path)
@ -2080,10 +2082,14 @@ class _AnnotationForTask(_Annotation):
im_w = im_meta_data['original_size'][0]['width']
im_h = im_meta_data['original_size'][0]['height']
counter = 0
for shape_type in ["boxes", "polygons", "polylines", "points"]:
path_list = paths[shape_type]
for path in path_list:
path_id = path.client_id if path.client_id != -1 else counter
counter += 1
dump_dict = OrderedDict([
("id", str(path_id)),
("label", path.label.name),
])
if path.group_id:

@ -798,9 +798,14 @@ class PlayerView {
this._playerUI.on('contextmenu.playerContextMenu', (e) => {
if (!window.cvat.mode) {
$('.custom-menu').hide(100);
this._contextMenuUI.finish().show(100).offset({
top: e.pageY - 10,
left: e.pageX - 10,
this._contextMenuUI.finish().show(100);
let x = Math.min(e.pageX, this._playerUI[0].offsetWidth -
this._contextMenuUI[0].scrollWidth);
let y = Math.min(e.pageY, this._playerUI[0].offsetHeight -
this._contextMenuUI[0].scrollHeight);
this._contextMenuUI.offset({
left: x,
top: y,
});
e.preventDefault();
}

@ -50,7 +50,7 @@ class ShapeBufferModel extends Listener {
}
}
_makeObject(box, points, trackedObj) {
_makeObject(box, points, isTracked) {
if (!this._shape.type) {
return null;
}
@ -75,7 +75,7 @@ class ShapeBufferModel extends Listener {
box.frame = window.cvat.player.frames.current;
box.z_order = this._collection.zOrder(box.frame).max;
if (trackedObj) {
if (isTracked) {
object.shapes = [];
object.shapes.push(Object.assign(box, {
outside: false,
@ -180,18 +180,49 @@ class ShapeBufferModel extends Listener {
let startFrame = window.cvat.player.frames.start;
let originalImageSize = imageSizes[object.frame - startFrame] || imageSizes[0];
// Getting normalized coordinates [0..1]
let normalized = {};
if (this._shape.type === 'box') {
normalized.xtl = object.xtl / originalImageSize.width;
normalized.ytl = object.ytl / originalImageSize.height;
normalized.xbr = object.xbr / originalImageSize.width;
normalized.ybr = object.ybr / originalImageSize.height;
}
else {
normalized.points = [];
for (let point of PolyShapeModel.convertStringToNumberArray(object.points)) {
normalized.points.push({
x: point.x / originalImageSize.width,
y: point.y / originalImageSize.height,
});
}
}
let addedObjects = [];
while (numOfFrames > 0 && (object.frame + 1 <= window.cvat.player.frames.stop)) {
object.frame ++;
numOfFrames --;
// Propagate only for frames with same size
object.z_order = this._collection.zOrder(object.frame).max;
let imageSize = imageSizes[object.frame - startFrame] || imageSizes[0];
if ((imageSize.width != originalImageSize.width) || (imageSize.height != originalImageSize.height)) {
continue;
let position = {};
if (this._shape.type === 'box') {
position.xtl = normalized.xtl * imageSize.width;
position.ytl = normalized.ytl * imageSize.height;
position.xbr = normalized.xbr * imageSize.width;
position.ybr = normalized.ybr * imageSize.height;
}
object.z_order = this._collection.zOrder(object.frame).max;
else {
position.points = [];
for (let point of normalized.points) {
position.points.push({
x: point.x * imageSize.width,
y: point.y * imageSize.height,
});
}
position.points = PolyShapeModel.convertNumberArrayToString(position.points);
}
Object.assign(object, position);
this._collection.add(object, `annotation_${this._shape.type}`);
addedObjects.push(this._collection.shapes.slice(-1)[0]);
}
@ -251,8 +282,24 @@ class ShapeBufferController {
let propagateHandler = Logger.shortkeyLogDecorator(function() {
if (!propagateDialogShowed) {
if (this._model.copyToBuffer()) {
let curFrame = window.cvat.player.frames.current;
let startFrame = window.cvat.player.frames.start;
let endFrame = Math.min(window.cvat.player.frames.stop, curFrame + this._model.propagateFrames);
let imageSizes = window.cvat.job.images.original_size;
let message = `Propagate up to ${endFrame} frame. `;
let refSize = imageSizes[curFrame - startFrame] || imageSizes[0];
for (let _frame = curFrame + 1; _frame <= endFrame; _frame ++) {
let size = imageSizes[_frame - startFrame] || imageSizes[0];
if ((size.width != refSize.width) || (size.height != refSize.height) ) {
message += 'Some covered frames have another resolution. Shapes in them can differ from reference. ';
break;
}
}
message += 'Are you sure?';
propagateDialogShowed = true;
confirm(`Propagate to ${this._model.propagateFrames} frames. Are you sure?`, () => {
confirm(message, () => {
this._model.propagateToFrames();
propagateDialogShowed = false;
}, () => propagateDialogShowed = false);
@ -402,7 +449,7 @@ class ShapeBufferView {
let area = w * h;
let type = this._shape.type;
if (area > AREA_TRESHOLD || type === 'points' || type === 'polyline' && (w >= AREA_TRESHOLD || h >= AREA_TRESHOLD)) {
if (area >= AREA_TRESHOLD || type === 'points' || type === 'polyline' && (w >= AREA_TRESHOLD || h >= AREA_TRESHOLD)) {
this._controller.pasteToFrame(e, null, actualPoints);
}
else {

@ -1423,6 +1423,7 @@ class ShapeView extends Listener {
this._pointContextMenu = $('#pointContextMenu');
this._rightBorderFrame = $('#playerFrame')[0].offsetWidth;
this._bottomBorderFrame = $('#playerFrame')[0].offsetHeight;
shapeModel.subscribe(this);
}
@ -1541,9 +1542,12 @@ class ShapeView extends Listener {
dragPolyItem.addClass('hidden');
}
this._shapeContextMenu.finish().show(100).offset({
top: e.pageY - 10,
left: e.pageX - 10,
this._shapeContextMenu.finish().show(100);
let x = Math.min(e.pageX, this._rightBorderFrame - this._shapeContextMenu[0].scrollWidth);
let y = Math.min(e.pageY, this._bottomBorderFrame - this._shapeContextMenu[0].scrollHeight);
this._shapeContextMenu.offset({
left: x,
top: y,
});
e.preventDefault();
@ -2437,7 +2441,7 @@ class ShapeView extends Listener {
if (this._uis.text && this._uis.text.node.parentElement) {
let revscale = 1 / scale;
let shapeBBox = this._uis.shape.node.getBBox();
let textBBox = this._uis.text.node.getBBox()
let textBBox = this._uis.text.node.getBBox();
let x = shapeBBox.x + shapeBBox.width + TEXT_MARGIN * revscale;
let y = shapeBBox.y;
@ -2826,9 +2830,12 @@ class PolyShapeView extends ShapeView {
this._pointContextMenu.attr('point_idx', point.index());
this._pointContextMenu.attr('dom_point_id', point.attr('id'));
this._pointContextMenu.finish().show(100).offset({
top: e.pageY - 20,
left: e.pageX - 20,
this._pointContextMenu.finish().show(100);
let x = Math.min(e.pageX, this._rightBorderFrame - this._pointContextMenu[0].scrollWidth);
let y = Math.min(e.pageY, this._bottomBorderFrame - this._pointContextMenu[0].scrollHeight);
this._pointContextMenu.offset({
left: x,
top: y,
});
e.preventDefault();
@ -3037,14 +3044,15 @@ class PointsView extends PolyShapeView {
return;
}
this._uis.points = this._scenes.svg.group().fill(this._appearance.fill || this._appearance.colors.shape)
this._uis.points = this._scenes.svg.group()
.fill(this._appearance.fill || this._appearance.colors.shape)
.on('click', () => {
this._positionateMenus();
this._controller.click();
}).attr({
'z_order': position.z_order
}).addClass('pointTempGroup');
this._uis.points.node.setAttribute('z_order', position.z_order);
let points = PolyShapeModel.convertStringToNumberArray(position.points);
for (let point of points) {
let radius = POINT_RADIUS * 2 / window.cvat.player.geometry.scale;
@ -3079,7 +3087,7 @@ class PointsView extends PolyShapeView {
let interpolation = this._controller.interpolate(window.cvat.player.frames.current);
if (interpolation.position.points) {
let points = window.cvat.translate.points.actualToCanvas(interpolation.position.points);
this._drawPointMarkers(Object.assign(interpolation.position.points, {points: points}));
this._drawPointMarkers(Object.assign(interpolation.position, {points: points}));
}
}
}

@ -26,6 +26,7 @@ from django.db import transaction
from ffmpy import FFmpeg
from pyunpack import Archive
from distutils.dir_util import copy_tree
from collections import OrderedDict
from . import models
from .log import slogger
@ -154,7 +155,7 @@ def get(tid):
"""Get the task as dictionary of attributes"""
db_task = models.Task.objects.get(pk=tid)
if db_task:
db_labels = db_task.label_set.prefetch_related('attributespec_set').all()
db_labels = db_task.label_set.prefetch_related('attributespec_set').order_by('-pk').all()
im_meta_data = get_image_meta_cache(db_task)
attributes = {}
for db_label in db_labels:
@ -174,7 +175,7 @@ def get(tid):
response = {
"status": db_task.status,
"spec": {
"labels": { db_label.id:db_label.name for db_label in db_labels },
"labels": OrderedDict((db_label.id, db_label.name) for db_label in db_labels),
"attributes": attributes
},
"size": db_task.size,
@ -228,7 +229,7 @@ def get_job(jid):
if db_task.mode == 'annotation':
im_meta_data['original_size'] = im_meta_data['original_size'][db_segment.start_frame:db_segment.stop_frame + 1]
db_labels = db_task.label_set.prefetch_related('attributespec_set').all()
db_labels = db_task.label_set.prefetch_related('attributespec_set').order_by('-pk').all()
attributes = {}
for db_label in db_labels:
attributes[db_label.id] = {}
@ -237,7 +238,7 @@ def get_job(jid):
response = {
"status": db_job.status,
"labels": { db_label.id:db_label.name for db_label in db_labels },
"labels": OrderedDict((db_label.id, db_label.name) for db_label in db_labels),
"stop": db_segment.stop_frame,
"taskid": db_task.id,
"slug": db_task.name,
@ -375,7 +376,7 @@ def _get_frame_path(frame, base_dir):
return path
def _parse_labels(labels):
parsed_labels = {}
parsed_labels = OrderedDict()
last_label = ""
for token in shlex.split(labels):

@ -52,6 +52,8 @@ module.exports = {
'createExportContainer': true,
'ExportType': true,
'getExportTargetContainer': true,
'IncrementIdGenerator': true,
'ConstIdGenerator': true,
// from shapeCollection.js
'ShapeCollectionModel': true,
'ShapeCollectionController': true,

Loading…
Cancel
Save