Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image rotation in client part #305

Merged
merged 15 commits into from
Feb 5, 2019
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