Skip to content

Commit 7e20b27

Browse files
authored
Added support of skeletons (#1)
1 parent 5f58a0f commit 7e20b27

File tree

291 files changed

+10882
-6098
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

291 files changed

+10882
-6098
lines changed

.eslintrc.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ module.exports = {
2424
'plugin:import/typescript', 'plugin:@typescript-eslint/recommended', 'airbnb-typescript/base',
2525
],
2626
rules: {
27-
'header/header': [2, 'line', [{
28-
pattern: ' {1}Copyright \\(C\\) (?:20\\d{2}-)?2022 Intel Corporation',
29-
template: ' Copyright (C) 2022 Intel Corporation'
30-
}, '', ' SPDX-License-Identifier: MIT']],
27+
// 'header/header': [2, 'line', [{
28+
// pattern: ' {1}Copyright \\(C\\) (?:20\\d{2}-)?2022 Intel Corporation',
29+
// template: ' Copyright (C) 2022 Intel Corporation'
30+
// }, '', ' SPDX-License-Identifier: MIT']],
3131
'no-plusplus': 0,
3232
'no-continue': 0,
3333
'no-console': 0,
@@ -52,6 +52,7 @@ module.exports = {
5252
'import/order': ['error', {'groups': ['builtin', 'external', 'internal']}],
5353
'import/prefer-default-export': 0, // works incorrect with interfaces
5454

55+
'@typescript-eslint/ban-ts-comment': 0,
5556
'@typescript-eslint/no-explicit-any': 0,
5657
'@typescript-eslint/indent': ['error', 4],
5758
'@typescript-eslint/lines-between-class-members': 0,

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## \[2.2.0] - Unreleased
99
### Added
10+
- Added ability to delete frames from a job based on (<https://github.com/openvinotoolkit/cvat/pull/4194>)
1011
- Support of attributes returned by serverless functions based on (<https://github.com/openvinotoolkit/cvat/pull/4506>)
1112
- Project/task backups uploading via chunk uploads
1213
- Fixed UX bug when jobs pagination is reset after changing a job
@@ -21,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2122
- Documentation for LDAP authentication (<https://github.com/cvat-ai/cvat/pull/39>)
2223
- OpenCV.js caching and autoload (<https://github.com/cvat-ai/cvat/pull/30>)
2324
- Publishing dev version of CVAT docker images (<https://github.com/cvat-ai/cvat/pull/53>)
25+
- Support of Human Pose Estimation, Facial Landmarks (and similar) use-cases, new shape type: Skeleton (<https://github.com/cvat-ai/cvat/pull/1>)
2426

2527
### Changed
2628
- Bumped nuclio version to 1.8.14
@@ -57,7 +59,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5759
- Advanced filtration and sorting for a list of tasks/projects/cloudstorages (<https://github.com/openvinotoolkit/cvat/pull/4403>)
5860
- Project dataset importing via chunk uploads (<https://github.com/openvinotoolkit/cvat/pull/4485>)
5961
- Support paginated list for job commits (<https://github.com/openvinotoolkit/cvat/pull/4482>)
60-
- Added ability to delete frames from a job (<https://github.com/openvinotoolkit/cvat/pull/4194>)
6162

6263
### Changed
6364
- Added missing geos dependency into Dockerfile (<https://github.com/openvinotoolkit/cvat/pull/4451>)

cvat-canvas/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cvat-canvas",
3-
"version": "2.14.0",
3+
"version": "2.15.0",
44
"description": "Part of Computer Vision Annotation Tool which presents its canvas library",
55
"main": "src/canvas.ts",
66
"scripts": {

cvat-canvas/src/scss/canvas.scss

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010
stroke-opacity: 1;
1111
}
1212

13+
g.cvat_canvas_shape {
14+
> circle {
15+
fill-opacity: 1;
16+
}
17+
}
18+
1319
polyline.cvat_canvas_shape {
1420
fill-opacity: 0;
1521
}
@@ -120,7 +126,6 @@ polyline.cvat_canvas_shape_splitting {
120126
@extend .cvat_shape_drawing_opacity;
121127

122128
fill: white;
123-
stroke: black;
124129
}
125130

126131
.cvat_canvas_zoom_selection {
@@ -134,6 +139,12 @@ polyline.cvat_canvas_shape_splitting {
134139
stroke-dasharray: 5;
135140
}
136141

142+
g.cvat_canvas_shape_occluded {
143+
> rect {
144+
stroke-dasharray: 5;
145+
}
146+
}
147+
137148
.svg_select_points_rot {
138149
fill: white;
139150
}
@@ -226,6 +237,12 @@ polyline.cvat_canvas_shape_splitting {
226237
}
227238
}
228239

240+
.cvat_canvas_skeleton_wrapping_rect {
241+
// wrapping rect must not apply transform attribute from selectize.js
242+
// otherwise it rotated twice, because we apply the same rotation value to parent element (skeleton itself)
243+
transform: none !important;
244+
}
245+
229246
.cvat_canvas_pixelized {
230247
image-rendering: optimizeSpeed; /* Legal fallback */
231248
image-rendering: -moz-crisp-edges; /* Firefox */

cvat-canvas/src/typescript/autoborderHandler.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import * as SVG from 'svg.js';
66

77
import consts from './consts';
8-
import { Geometry } from './canvasModel';
8+
import { Configuration, Geometry } from './canvasModel';
99

1010
interface TransformedShape {
1111
points: string;
@@ -14,6 +14,7 @@ interface TransformedShape {
1414

1515
export interface AutoborderHandler {
1616
autoborder(enabled: boolean, currentShape?: SVG.Shape, currentID?: number): void;
17+
configurate(configuration: Configuration): void;
1718
transform(geometry: Geometry): void;
1819
updateObjects(): void;
1920
}
@@ -24,19 +25,14 @@ export class AutoborderHandlerImpl implements AutoborderHandler {
2425
private frameContent: SVGSVGElement;
2526
private enabled: boolean;
2627
private scale: number;
28+
private controlPointsSize: number;
2729
private groups: SVGGElement[];
2830
private auxiliaryGroupID: number | null;
2931
private auxiliaryClicks: number[];
30-
private listeners: Record<
31-
number,
32-
Record<
33-
number,
34-
{
32+
private listeners: Record<number, Record<number, {
3533
click: (event: MouseEvent) => void;
3634
dblclick: (event: MouseEvent) => void;
37-
}
38-
>
39-
>;
35+
}>>;
4036

4137
public constructor(frameContent: SVGSVGElement) {
4238
this.frameContent = frameContent;
@@ -45,6 +41,7 @@ export class AutoborderHandlerImpl implements AutoborderHandler {
4541
this.enabled = false;
4642
this.scale = 1;
4743
this.groups = [];
44+
this.controlPointsSize = consts.BASE_POINT_SIZE;
4845
this.auxiliaryGroupID = null;
4946
this.auxiliaryClicks = [];
5047
this.listeners = {};
@@ -126,7 +123,7 @@ export class AutoborderHandlerImpl implements AutoborderHandler {
126123
circle.setAttribute('stroke-width', `${consts.POINTS_STROKE_WIDTH / this.scale}`);
127124
circle.setAttribute('cx', x);
128125
circle.setAttribute('cy', y);
129-
circle.setAttribute('r', `${consts.BASE_POINT_SIZE / this.scale}`);
126+
circle.setAttribute('r', `${this.controlPointsSize / this.scale}`);
130127

131128
const click = (event: MouseEvent): void => {
132129
event.stopPropagation();
@@ -303,9 +300,13 @@ export class AutoborderHandlerImpl implements AutoborderHandler {
303300
this.scale = geometry.scale;
304301
this.groups.forEach((group: SVGGElement): void => {
305302
Array.from(group.children).forEach((circle: SVGCircleElement): void => {
306-
circle.setAttribute('r', `${consts.BASE_POINT_SIZE / this.scale}`);
303+
circle.setAttribute('r', `${this.controlPointsSize / this.scale}`);
307304
circle.setAttribute('stroke-width', `${consts.BASE_STROKE_WIDTH / this.scale}`);
308305
});
309306
});
310307
}
308+
309+
public configurate(configuration: Configuration): void {
310+
this.controlPointsSize = configuration.controlPointsSize || consts.BASE_POINT_SIZE;
311+
}
311312
}

cvat-canvas/src/typescript/canvasModel.ts

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,20 @@ export interface Configuration {
6464
forceDisableEditing?: boolean;
6565
intelligentPolygonCrop?: boolean;
6666
forceFrameUpdate?: boolean;
67-
creationOpacity?: number;
6867
CSSImageFilter?: string;
68+
colorBy?: string;
69+
selectedShapeOpacity?: number;
70+
shapeOpacity?: number;
71+
controlPointsSize?: number;
72+
outlinedBorders?: string | false;
6973
}
7074

7175
export interface DrawData {
7276
enabled: boolean;
7377
shapeType?: string;
7478
rectDrawingMethod?: RectDrawingMethod;
7579
cuboidDrawingMethod?: CuboidDrawingMethod;
80+
skeletonSVG?: string;
7681
numberOfPoints?: number;
7782
initialState?: any;
7883
crosshair?: boolean;
@@ -265,12 +270,23 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
265270
width: 0,
266271
},
267272
configuration: {
268-
displayAllText: false,
273+
smoothImage: true,
269274
autoborders: false,
270-
undefinedAttrValue: '',
271-
textContent: 'id,label,attributes,source,descriptions',
272-
textPosition: 'auto',
275+
displayAllText: false,
276+
showProjections: false,
277+
forceDisableEditing: false,
278+
intelligentPolygonCrop: false,
279+
forceFrameUpdate: false,
280+
CSSImageFilter: '',
281+
colorBy: 'Label',
282+
selectedShapeOpacity: 0.5,
283+
shapeOpacity: 0.2,
284+
outlinedBorders: false,
273285
textFontSize: consts.DEFAULT_SHAPE_TEXT_SIZE,
286+
controlPointsSize: consts.BASE_POINT_SIZE,
287+
textPosition: consts.DEFAULT_SHAPE_TEXT_POSITION,
288+
textContent: consts.DEFAULT_SHAPE_TEXT_CONTENT,
289+
undefinedAttrValue: consts.DEFAULT_UNDEFINED_ATTR_VALUE,
274290
},
275291
imageBitmap: false,
276292
image: null,
@@ -541,6 +557,10 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
541557
}
542558

543559
if (drawData.enabled) {
560+
if (drawData.shapeType === 'skeleton' && !drawData.skeletonSVG) {
561+
throw new Error('Skeleton template must be specified when drawing a skeleton');
562+
}
563+
544564
if (this.data.drawData.enabled) {
545565
throw new Error('Drawing has been already started');
546566
} else if (!drawData.shapeType && !drawData.initialState) {
@@ -670,6 +690,10 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
670690
this.data.configuration.textFontSize = configuration.textFontSize;
671691
}
672692

693+
if (typeof configuration.controlPointsSize === 'number') {
694+
this.data.configuration.controlPointsSize = configuration.controlPointsSize;
695+
}
696+
673697
if (['auto', 'center'].includes(configuration.textPosition)) {
674698
this.data.configuration.textPosition = configuration.textPosition;
675699
}
@@ -702,8 +726,17 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
702726
if (typeof configuration.forceFrameUpdate === 'boolean') {
703727
this.data.configuration.forceFrameUpdate = configuration.forceFrameUpdate;
704728
}
705-
if (typeof configuration.creationOpacity === 'number') {
706-
this.data.configuration.creationOpacity = configuration.creationOpacity;
729+
if (typeof configuration.selectedShapeOpacity === 'number') {
730+
this.data.configuration.selectedShapeOpacity = configuration.selectedShapeOpacity;
731+
}
732+
if (typeof configuration.shapeOpacity === 'number') {
733+
this.data.configuration.shapeOpacity = configuration.shapeOpacity;
734+
}
735+
if (['string', 'boolean'].includes(typeof configuration.outlinedBorders)) {
736+
this.data.configuration.outlinedBorders = configuration.outlinedBorders;
737+
}
738+
if (['Instance', 'Group', 'Label'].includes(configuration.colorBy)) {
739+
this.data.configuration.colorBy = configuration.colorBy;
707740
}
708741

709742
if (typeof configuration.CSSImageFilter === 'string') {

0 commit comments

Comments
 (0)