Skip to content

Commit

Permalink
Merge pull request #8678 from cvat-ai/release-2.22.0
Browse files Browse the repository at this point in the history
Release v2.22.0
  • Loading branch information
cvat-bot[bot] authored Nov 11, 2024
2 parents 8d990c9 + 333df35 commit c737f08
Show file tree
Hide file tree
Showing 236 changed files with 3,147 additions and 2,152 deletions.
33 changes: 3 additions & 30 deletions .github/workflows/black.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- id: files
uses: tj-actions/[email protected]
with:
files: |
cvat-sdk/**/*.py
cvat-cli/**/*.py
tests/python/**/*.py
cvat/apps/quality_control/**/*.py
cvat/apps/analytics_report/**/*.py
dir_names: true

- name: Run checks
env:
PR_FILES_AM: ${{ steps.files.outputs.added_modified }}
PR_FILES_RENAMED: ${{ steps.files.outputs.renamed }}
run: |
# If different modules use different Black configs,
# we need to run Black for each python component group separately.
# Otherwise, they all will use the same config.
pipx install $(grep "^black" ./cvat-cli/requirements/development.txt)
UPDATED_DIRS="${{steps.files.outputs.all_changed_files}}"
echo "Black version: $(black --version)"
if [[ ! -z $UPDATED_DIRS ]]; then
pipx install $(egrep "black.*" ./cvat-cli/requirements/development.txt)
echo "Black version: "$(black --version)
echo "The dirs will be checked: $UPDATED_DIRS"
EXIT_CODE=0
for DIR in $UPDATED_DIRS; do
black --check --diff $DIR || EXIT_CODE=$(($? | $EXIT_CODE)) || true
done
exit $EXIT_CODE
else
echo "No files with the \"py\" extension found"
fi
black --check --diff .
2 changes: 1 addition & 1 deletion .github/workflows/finalize-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:

- name: Bump version
run:
./dev/update_version.py --minor
./dev/update_version.py --patch

- name: Commit post-release changes
run: |
Expand Down
49 changes: 49 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,55 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

<!-- scriv-insert-here -->

<a id='changelog-2.22.0'></a>
## \[2.22.0\] - 2024-11-11

### Added

- Feature to hide a mask during editing (<https://github.com/cvat-ai/cvat/pull/8554>)

- A quality setting to compare point groups without using bbox
(<https://github.com/cvat-ai/cvat/pull/8634>)

- A quality check option to consider empty frames matching
(<https://github.com/cvat-ai/cvat/pull/8652>)

### Changed

- Reduced memory usage of the utils container
(<https://github.com/cvat-ai/cvat/pull/8672>)

### Removed

- Removed unused business group
(<https://github.com/cvat-ai/cvat/pull/8607>)

### Fixed

- Propagation creates copies on non-existing frames in a ground truth job
(<https://github.com/cvat-ai/cvat/pull/8550>)

- Exporting projects with tasks containing honeypots. Honeypots are no longer exported.
(<https://github.com/cvat-ai/cvat/pull/8597>)

- Error after creating GT job on Create job page with frame selection method `random_per_job`
(<https://github.com/cvat-ai/cvat/pull/8623>)

- Fixed issue 'Cannot read properties of undefined (reading 'push')'
(<https://github.com/cvat-ai/cvat/pull/8648>)

- Re-newed import/export request failed immediately if the previous failed
(<https://github.com/cvat-ai/cvat/pull/8649>)

- Fixed automatic zooming in attribute annotation mode for masks
(<https://github.com/cvat-ai/cvat/pull/8657>)

- Export dataset in CVAT format misses frames in tasks with non-default frame step
(<https://github.com/cvat-ai/cvat/pull/8662>)

- Incorrect progress representation on `Requests` page
(<https://github.com/cvat-ai/cvat/pull/8668>)

<a id='changelog-2.21.3'></a>
## \[2.21.3\] - 2024-10-31

Expand Down
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.20.9",
"version": "2.20.10",
"type": "module",
"description": "Part of Computer Vision Annotation Tool which presents its canvas library",
"main": "src/canvas.ts",
Expand Down
6 changes: 6 additions & 0 deletions cvat-canvas/src/typescript/canvasModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export interface Configuration {
controlPointsSize?: number;
outlinedBorders?: string | false;
resetZoom?: boolean;
hideEditedObject?: boolean;
}

export interface BrushTool {
Expand Down Expand Up @@ -416,6 +417,7 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
textPosition: consts.DEFAULT_SHAPE_TEXT_POSITION,
textContent: consts.DEFAULT_SHAPE_TEXT_CONTENT,
undefinedAttrValue: consts.DEFAULT_UNDEFINED_ATTR_VALUE,
hideEditedObject: false,
},
imageBitmap: false,
image: null,
Expand Down Expand Up @@ -981,6 +983,10 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
this.data.configuration.CSSImageFilter = configuration.CSSImageFilter;
}

if (typeof configuration.hideEditedObject === 'boolean') {
this.data.configuration.hideEditedObject = configuration.hideEditedObject;
}

this.notify(UpdateReasons.CONFIG_UPDATED);
}

Expand Down
27 changes: 19 additions & 8 deletions cvat-canvas/src/typescript/canvasView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1918,15 +1918,26 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.gridPattern.setAttribute('height', `${size.height}`);
} else if (reason === UpdateReasons.SHAPE_FOCUSED) {
const { padding, clientID } = this.controller.focusData;
const drawnState = this.drawnStates[clientID];
const object = this.svgShapes[clientID];
if (object) {
const bbox: SVG.BBox = object.bbox();
this.onFocusRegion(
bbox.x - padding,
bbox.y - padding,
bbox.width + padding * 2,
bbox.height + padding * 2,
);
if (drawnState && object) {
const { offset } = this.geometry;
let [x, y, width, height] = [0, 0, 0, 0];

if (drawnState.shapeType === 'mask') {
const [xtl, ytl, xbr, ybr] = drawnState.points.slice(-4);
x = xtl + offset;
y = ytl + offset;
width = xbr - xtl + 1;
height = ybr - ytl + 1;
} else {
const bbox: SVG.BBox = object.bbox();
({
x, y, width, height,
} = bbox);
}

this.onFocusRegion(x - padding, y - padding, width + padding * 2, height + padding * 2);
}
} else if (reason === UpdateReasons.SHAPE_ACTIVATED) {
this.activate(this.controller.activeElement);
Expand Down
40 changes: 36 additions & 4 deletions cvat-canvas/src/typescript/drawHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import * as SVG from 'svg.js';
import 'svg.draw.js';
import './svg.patch';
import { CIRCLE_STROKE } from './svg.patch';

import { AutoborderHandler } from './autoborderHandler';
import {
Expand Down Expand Up @@ -104,6 +104,7 @@ export class DrawHandlerImpl implements DrawHandler {
private controlPointsSize: number;
private selectedShapeOpacity: number;
private outlinedBorders: string;
private isHidden: boolean;

// we should use any instead of SVG.Shape because svg plugins cannot change declared interface
// so, methods like draw() just undefined for SVG.Shape, but nevertheless they exist
Expand Down Expand Up @@ -1276,6 +1277,7 @@ export class DrawHandlerImpl implements DrawHandler {
this.selectedShapeOpacity = configuration.selectedShapeOpacity;
this.outlinedBorders = configuration.outlinedBorders || 'black';
this.autobordersEnabled = false;
this.isHidden = false;
this.startTimestamp = Date.now();
this.onDrawDoneDefault = onDrawDone;
this.canvas = canvas;
Expand All @@ -1301,10 +1303,28 @@ export class DrawHandlerImpl implements DrawHandler {
});
}

private strokePoint(point: SVG.Element): void {
point.attr('stroke', this.isHidden ? 'none' : CIRCLE_STROKE);
point.fill({ opacity: this.isHidden ? 0 : 1 });
}

private updateHidden(value: boolean) {
this.isHidden = value;

if (value) {
this.canvas.attr('pointer-events', 'none');
} else {
this.canvas.attr('pointer-events', 'all');
}
}

public configurate(configuration: Configuration): void {
this.controlPointsSize = configuration.controlPointsSize;
this.selectedShapeOpacity = configuration.selectedShapeOpacity;
this.outlinedBorders = configuration.outlinedBorders || 'black';
if (this.isHidden !== configuration.hideEditedObject) {
this.updateHidden(configuration.hideEditedObject);
}

const isFillableRect = this.drawData &&
this.drawData.shapeType === 'rectangle' &&
Expand All @@ -1315,15 +1335,26 @@ export class DrawHandlerImpl implements DrawHandler {
const isFilalblePolygon = this.drawData && this.drawData.shapeType === 'polygon';

if (this.drawInstance && (isFillableRect || isFillableCuboid || isFilalblePolygon)) {
this.drawInstance.fill({ opacity: configuration.selectedShapeOpacity });
this.drawInstance.fill({
opacity: configuration.hideEditedObject ? 0 : configuration.selectedShapeOpacity,
});
}

if (this.drawInstance && (isFilalblePolygon)) {
const paintHandler = this.drawInstance.remember('_paintHandler');
if (paintHandler) {
for (const point of (paintHandler as any).set.members) {
this.strokePoint(point);
}
}
}

if (this.drawInstance && this.drawInstance.attr('stroke')) {
this.drawInstance.attr('stroke', this.outlinedBorders);
this.drawInstance.attr('stroke', configuration.hideEditedObject ? 'none' : this.outlinedBorders);
}

if (this.pointsGroup && this.pointsGroup.attr('stroke')) {
this.pointsGroup.attr('stroke', this.outlinedBorders);
this.pointsGroup.attr('stroke', configuration.hideEditedObject ? 'none' : this.outlinedBorders);
}

this.autobordersEnabled = configuration.autoborders;
Expand Down Expand Up @@ -1369,6 +1400,7 @@ export class DrawHandlerImpl implements DrawHandler {
const paintHandler = this.drawInstance.remember('_paintHandler');

for (const point of (paintHandler as any).set.members) {
this.strokePoint(point);
point.attr('stroke-width', `${consts.POINTS_STROKE_WIDTH / geometry.scale}`);
point.attr('r', `${this.controlPointsSize / geometry.scale}`);
}
Expand Down
2 changes: 1 addition & 1 deletion cvat-canvas/src/typescript/editHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ export class EditHandlerImpl implements EditHandler {

const paintHandler = this.editLine.remember('_paintHandler');

for (const point of (paintHandler as any).set.members) {
for (const point of paintHandler.set.members) {
point.attr('stroke-width', `${consts.POINTS_STROKE_WIDTH / geometry.scale}`);
point.attr('r', `${this.controlPointsSize / geometry.scale}`);
}
Expand Down
43 changes: 36 additions & 7 deletions cvat-canvas/src/typescript/masksHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { fabric } from 'fabric';
import debounce from 'lodash/debounce';

import {
DrawData, MasksEditData, Geometry, Configuration, BrushTool, ColorBy,
DrawData, MasksEditData, Geometry, Configuration, BrushTool, ColorBy, Position,
} from './canvasModel';
import consts from './consts';
import { DrawHandler } from './drawHandler';
Expand Down Expand Up @@ -61,10 +61,11 @@ export class MasksHandlerImpl implements MasksHandler {
private editData: MasksEditData | null;

private colorBy: ColorBy;
private latestMousePos: { x: number; y: number; };
private latestMousePos: Position;
private startTimestamp: number;
private geometry: Geometry;
private drawingOpacity: number;
private isHidden: boolean;

private keepDrawnPolygon(): void {
const canvasWrapper = this.canvas.getElement().parentElement;
Expand Down Expand Up @@ -217,12 +218,29 @@ export class MasksHandlerImpl implements MasksHandler {
private imageDataFromCanvas(wrappingBBox: WrappingBBox): Uint8ClampedArray {
const imageData = this.canvas.toCanvasElement()
.getContext('2d').getImageData(
wrappingBBox.left, wrappingBBox.top,
wrappingBBox.right - wrappingBBox.left + 1, wrappingBBox.bottom - wrappingBBox.top + 1,
wrappingBBox.left,
wrappingBBox.top,
wrappingBBox.right - wrappingBBox.left + 1,
wrappingBBox.bottom - wrappingBBox.top + 1,
).data;
return imageData;
}

private updateHidden(value: boolean) {
this.isHidden = value;

// Need to update style of upper canvas explicitly because update of default cursor is not applied immediately
// https://github.com/fabricjs/fabric.js/issues/1456
const newOpacity = value ? '0' : '';
const newCursor = value ? 'inherit' : 'none';
this.canvas.getElement().parentElement.style.opacity = newOpacity;
const upperCanvas = this.canvas.getElement().parentElement.querySelector('.upper-canvas') as HTMLElement;
if (upperCanvas) {
upperCanvas.style.cursor = newCursor;
}
this.canvas.defaultCursor = newCursor;
}

private updateBrushTools(brushTool?: BrushTool, opts: Partial<BrushTool> = {}): void {
if (this.isPolygonDrawing) {
// tool was switched from polygon to brush for example
Expand Down Expand Up @@ -350,6 +368,7 @@ export class MasksHandlerImpl implements MasksHandler {
this.editData = null;
this.drawingOpacity = 0.5;
this.brushMarker = null;
this.isHidden = false;
this.colorBy = ColorBy.LABEL;
this.onDrawDone = onDrawDone;
this.onDrawRepeat = onDrawRepeat;
Expand Down Expand Up @@ -452,7 +471,7 @@ export class MasksHandlerImpl implements MasksHandler {
this.canvas.renderAll();
}

if (isMouseDown && !isBrushSizeChanging && ['brush', 'eraser'].includes(tool?.type)) {
if (isMouseDown && !this.isHidden && !isBrushSizeChanging && ['brush', 'eraser'].includes(tool?.type)) {
const color = fabric.Color.fromHex(tool.color);
color.setAlpha(tool.type === 'eraser' ? 1 : 0.5);

Expand Down Expand Up @@ -530,6 +549,10 @@ export class MasksHandlerImpl implements MasksHandler {

public configurate(configuration: Configuration): void {
this.colorBy = configuration.colorBy;

if (this.isHidden !== configuration.hideEditedObject) {
this.updateHidden(configuration.hideEditedObject);
}
}

public transform(geometry: Geometry): void {
Expand Down Expand Up @@ -563,7 +586,10 @@ export class MasksHandlerImpl implements MasksHandler {
const color = fabric.Color.fromHex(this.getStateColor(drawData.initialState)).getSource();
const [left, top, right, bottom] = points.slice(-4);
const imageBitmap = expandChannels(color[0], color[1], color[2], points);
imageDataToDataURL(imageBitmap, right - left + 1, bottom - top + 1,
imageDataToDataURL(
imageBitmap,
right - left + 1,
bottom - top + 1,
(dataURL: string) => new Promise((resolve) => {
fabric.Image.fromURL(dataURL, (image: fabric.Image) => {
try {
Expand Down Expand Up @@ -654,7 +680,10 @@ export class MasksHandlerImpl implements MasksHandler {
const color = fabric.Color.fromHex(this.getStateColor(editData.state)).getSource();
const [left, top, right, bottom] = points.slice(-4);
const imageBitmap = expandChannels(color[0], color[1], color[2], points);
imageDataToDataURL(imageBitmap, right - left + 1, bottom - top + 1,
imageDataToDataURL(
imageBitmap,
right - left + 1,
bottom - top + 1,
(dataURL: string) => new Promise((resolve) => {
fabric.Image.fromURL(dataURL, (image: fabric.Image) => {
try {
Expand Down
2 changes: 2 additions & 0 deletions cvat-canvas/src/typescript/svg.patch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ SVG.Element.prototype.draw.extend(
}),
);

export const CIRCLE_STROKE = '#000';
// Fix method drawCircles
function drawCircles(): void {
const array = this.el.array().valueOf();
Expand All @@ -109,6 +110,7 @@ function drawCircles(): void {
.circle(5)
.stroke({
width: 1,
color: CIRCLE_STROKE,
})
.fill('#ccc')
.center(p.x, p.y),
Expand Down
Loading

0 comments on commit c737f08

Please sign in to comment.