Skip to content

Commit

Permalink
Image rotation in client part (#305)
Browse files Browse the repository at this point in the history
* Rotation shortcuts Ctrl+R, Ctrl+Shift+R
* Changelog has been updated
  • Loading branch information
bsekachev authored and nmanovic committed Feb 5, 2019
1 parent 46d2120 commit b4e6f22
Show file tree
Hide file tree
Showing 12 changed files with 341 additions and 138 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- OpenVINO auto annotation: it is possible to upload a custom model and annotate images automatically.
- Ability to rotate images/video in the client part (Ctrl+R, Shift+Ctrl+R shortcuts) (#305)

### Changed
- Propagation setup has been moved from settings to bottom player panel
Expand Down
23 changes: 8 additions & 15 deletions cvat/apps/engine/static/engine/js/annotationUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -653,13 +653,11 @@ function setupMenu(job, shapeCollectionModel, annotationParser, aamModel, player
}


function drawBoxSize(scene, box) {
let scale = window.cvat.player.geometry.scale;
let width = +box.getAttribute('width');
let height = +box.getAttribute('height');
let text = `${width.toFixed(1)}x${height.toFixed(1)}`;
function drawBoxSize(boxScene, textScene, box) {
let clientBox = window.cvat.translate.box.canvasToClient(boxScene.node, box);
let text = `${box.width.toFixed(1)}x${box.height.toFixed(1)}`;
let obj = this && this.textUI && this.rm ? this : {
textUI: scene.text('').font({
textUI: textScene.text('').font({
weight: 'bolder'
}).fill('white'),

Expand All @@ -670,16 +668,11 @@ function drawBoxSize(scene, box) {
}
};

obj.textUI.clear().plain(text);

obj.textUI.font({
size: 20 / scale,
}).style({
stroke: 'black',
'stroke-width': 1 / scale
});
let textPoint = window.cvat.translate.point.clientToCanvas(textScene.node, clientBox.x, clientBox.y);

obj.textUI.move(+box.getAttribute('x'), +box.getAttribute('y'));
obj.textUI.clear().plain(text);
obj.textUI.addClass("shapeText");
obj.textUI.move(textPoint.x, textPoint.y);

return obj;
}
Expand Down
42 changes: 42 additions & 0 deletions cvat/apps/engine/static/engine/js/coordinateTranslator.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,30 @@ class CoordinateTranslator {

return this._convert(actualBox, -1);
},

canvasToClient: function(sourceCanvas, canvasBox) {
let points = [
window.cvat.translate.point.canvasToClient(sourceCanvas, canvasBox.x, canvasBox.y),
window.cvat.translate.point.canvasToClient(sourceCanvas, canvasBox.x + canvasBox.width, canvasBox.y),
window.cvat.translate.point.canvasToClient(sourceCanvas, canvasBox.x, canvasBox.y + canvasBox.height),
window.cvat.translate.point.canvasToClient(sourceCanvas, canvasBox.x + canvasBox.width, canvasBox.y + canvasBox.height),
];

let xes = points.map((el) => el.x);
let yes = points.map((el) => el.y);

let xmin = Math.min(...xes);
let xmax = Math.max(...xes);
let ymin = Math.min(...yes);
let ymax = Math.max(...yes);

return {
x: xmin,
y: ymin,
width: xmax - xmin,
height: ymax - ymin
};
},
};

this._pointsTranslator = {
Expand Down Expand Up @@ -70,6 +94,7 @@ class CoordinateTranslator {
},

this._pointTranslator = {
_rotation: 0,
clientToCanvas: function(targetCanvas, clientX, clientY) {
let pt = targetCanvas.createSVGPoint();
pt.x = clientX;
Expand All @@ -83,6 +108,19 @@ class CoordinateTranslator {
pt.y = canvasY;
pt = pt.matrixTransform(sourceCanvas.getScreenCTM());
return pt;
},
rotate(x, y, cx, cy) {
cx = (typeof cx === "undefined" ? 0 : cx);
cy = (typeof cy === "undefined" ? 0 : cy);

let radians = (Math.PI / 180) * window.cvat.player.rotation;
let cos = Math.cos(radians);
let sin = Math.sin(radians);

return {
x: (cos * (x - cx)) + (sin * (y - cy)) + cx,
y: (cos * (y - cy)) - (sin * (x - cx)) + cy
}
}
};
}
Expand All @@ -103,4 +141,8 @@ class CoordinateTranslator {
this._boxTranslator._playerOffset = value;
this._pointsTranslator._playerOffset = value;
}

set rotation(value) {
this._pointTranslator._rotation = value;
}
}
3 changes: 3 additions & 0 deletions cvat/apps/engine/static/engine/js/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,8 @@ var Logger = {
debugInfo: 24,
// dumped as "Fit image". There are no additional required fields.
fitImage: 25,
// dumped as "Rotate image". There are no additional required fields.
rotateImage: 26,
},

/**
Expand Down Expand Up @@ -526,6 +528,7 @@ var Logger = {
case this.EventType.changeFrame: return 'Change frame';
case this.EventType.debugInfo: return 'Debug info';
case this.EventType.fitImage: return 'Fit image';
case this.EventType.rotateImage: return 'Rotate image';
default: return 'Unknown';
}
},
Expand Down
Loading

0 comments on commit b4e6f22

Please sign in to comment.