Skip to content

Commit

Permalink
Intelligent polygon editing (#1921)
Browse files Browse the repository at this point in the history
* Intelligent polygon ediing
  • Loading branch information
bsekachev authored Jul 24, 2020
1 parent 6a1e7af commit 1e2c826
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 45 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Source type support for tags, shapes and tracks (<https://github.com/opencv/cvat/pull/1192>)
- Source type support for CVAT Dumper/Loader (<https://github.com/opencv/cvat/pull/1192>)
- Intelligent polygon editing (<https://github.com/opencv/cvat/pull/1921>)

### Changed
- Smaller object details (<https://github.com/opencv/cvat/pull/1877>)
Expand Down
2 changes: 1 addition & 1 deletion cvat-canvas/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cvat-canvas/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cvat-canvas",
"version": "2.0.1",
"version": "2.0.2",
"description": "Part of Computer Vision Annotation Tool which presents its canvas library",
"main": "src/canvas.ts",
"scripts": {
Expand Down
121 changes: 78 additions & 43 deletions cvat-canvas/src/typescript/editHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,18 @@ export class EditHandlerImpl implements EditHandler {
});

this.editLine = (this.canvas as any).polyline();

if (this.editData.state.shapeType === 'polyline') {
(this.editLine as any).on('drawpoint', (e: CustomEvent): void => {
const circle = (e.target as any).instance.remember('_paintHandler').set.last();
if (circle) this.setupTrailingPoint(circle);
});
}

const strokeColor = this.editedShape.attr('stroke');
(this.editLine as any).addClass('cvat_canvas_shape_drawing').style({
'pointer-events': 'none',
'fill-opacity': 0,
'stroke': strokeColor,
}).attr({
'data-origin-client-id': this.editData.state.clientID,
}).on('drawstart drawpoint', (e: CustomEvent): void => {
Expand Down Expand Up @@ -180,23 +181,87 @@ export class EditHandlerImpl implements EditHandler {
const [start, stop] = [this.editData.pointID, stopPointID]
.sort((a, b): number => +a - +b);

if (this.editData.state.shapeType === 'polygon') {
if (start !== this.editData.pointID) {
linePoints.reverse();
if (this.editData.state.shapeType !== 'polygon') {
let points = null;
const { offset } = this.geometry;

if (this.editData.state.shapeType === 'polyline') {
if (start !== this.editData.pointID) {
linePoints.reverse();
}
points = oldPoints.slice(0, start)
.concat(linePoints)
.concat(oldPoints.slice(stop + 1));
} else {
points = oldPoints.concat(linePoints.slice(0, -1));
}

const firstPart = oldPoints.slice(0, start)
.concat(linePoints)
.concat(oldPoints.slice(stop + 1));
points = pointsToNumberArray(points.join(' '))
.map((coord: number): number => coord - offset);

const { state } = this.editData;
this.edit({
enabled: false,
});
this.onEditDone(state, points);

const secondPart = oldPoints.slice(start, stop)
.concat(linePoints.slice(1).reverse());
return;
}

if (firstPart.length < 3 || secondPart.length < 3) {
this.cancel();
return;
const cutIndexes1 = oldPoints.reduce((acc: string[], _: string, i: number) =>
i >= stop || i <= start ? [...acc, i] : acc, []);
const cutIndexes2 = oldPoints.reduce((acc: string[], _: string, i: number) =>
i <= stop && i >= start ? [...acc, i] : acc, []);

const curveLength = (indexes: number[]) => {
const points = indexes.map((index: number): string => oldPoints[index])
.map((point: string): string[] => point.split(','))
.map((point: string[]): number[] => [+point[0], +point[1]]);
let length = 0;
for (let i = 1; i < points.length; i++) {
length += Math.sqrt(
(points[i][0] - points[i - 1][0]) ** 2
+ (points[i][1] - points[i - 1][1]) ** 2,
);
}

return length;
}

const pointsCriteria = cutIndexes1.length > cutIndexes2.length;
const lengthCriteria = curveLength(cutIndexes1) > curveLength(cutIndexes2);

if (start !== this.editData.pointID) {
linePoints.reverse();
}

const firstPart = oldPoints.slice(0, start)
.concat(linePoints)
.concat(oldPoints.slice(stop + 1));
const secondPart = oldPoints.slice(start, stop)
.concat(linePoints.slice(1).reverse());

if (firstPart.length < 3 || secondPart.length < 3) {
this.cancel();
return;
}

// We do not need these events any more
this.canvas.off('mousedown.edit');
this.canvas.off('mousemove.edit');

(this.editLine as any).draw('stop');
this.editLine.remove();
this.editLine = null;

if (pointsCriteria && lengthCriteria) {
this.clones.push(this.canvas.polygon(firstPart.join(' ')));
this.selectPolygon(this.clones[0]);
// left indexes1 and
} else if (!pointsCriteria && !lengthCriteria) {
this.clones.push(this.canvas.polygon(secondPart.join(' ')));
this.selectPolygon(this.clones[0]);
} else {
for (const points of [firstPart, secondPart]) {
this.clones.push(this.canvas.polygon(points.join(' '))
.attr('fill', this.editedShape.attr('fill'))
Expand All @@ -212,39 +277,9 @@ export class EditHandlerImpl implements EditHandler {
clone.removeClass('cvat_canvas_shape_splitting');
});
}

// We do not need these events any more
this.canvas.off('mousedown.edit');
this.canvas.off('mousemove.edit');

(this.editLine as any).draw('stop');
this.editLine.remove();
this.editLine = null;

return;
}

let points = null;
const { offset } = this.geometry;
if (this.editData.state.shapeType === 'polyline') {
if (start !== this.editData.pointID) {
linePoints.reverse();
}
points = oldPoints.slice(0, start)
.concat(linePoints)
.concat(oldPoints.slice(stop + 1));
} else {
points = oldPoints.concat(linePoints.slice(0, -1));
}

points = pointsToNumberArray(points.join(' '))
.map((coord: number): number => coord - offset);

const { state } = this.editData;
this.edit({
enabled: false,
});
this.onEditDone(state, points);
return;
}

private setupPoints(enabled: boolean): void {
Expand Down

0 comments on commit 1e2c826

Please sign in to comment.