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

Release v2.22.0 #8678

Merged
merged 31 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7f5bc4b
Hide mask during editing (#8554)
klakhov Oct 31, 2024
e4c9def
removing business group (#8607)
Eldies Oct 31, 2024
16d4d75
Blacken code by default (#8611)
SpecLad Oct 31, 2024
663fab7
Fix exporting projects with honeypots (#8597)
Marishka17 Oct 31, 2024
e74d88d
Update develop after v2.21.3
cvat-bot[bot] Oct 31, 2024
a652191
Merge pull request #8624 from cvat-ai/dev-release-2.21.3
azhavoro Oct 31, 2024
f0a578a
Fixed missing keybind in tooltip (#8632)
bsekachev Nov 1, 2024
5dc5265
SDK: remove imports that were deprecated in Python 3.9 (#8626)
SpecLad Nov 1, 2024
a4a989d
Predefined number of points in single shape mode disabled by default …
bsekachev Nov 1, 2024
ceba1b7
Fixed propagate in ground truth tasks with sparsed frames (#8550)
bsekachev Nov 1, 2024
7ce5452
Fix `random_per_job` option on create job page (#8623)
klakhov Nov 2, 2024
fc385e9
Refactor all of CLI (#8614)
SpecLad Nov 4, 2024
67f9afd
Remove deprecated typing imports from generated SDK sources (#8637)
SpecLad Nov 4, 2024
2560a0d
CLI: remove imports that were deprecated in Python 3.9 (#8640)
SpecLad Nov 5, 2024
6a60642
Fix unstable honeypot reroll test (#8639)
zhiltsov-max Nov 5, 2024
1d0f5d6
Added test and docs for hide mask feature (#8633)
klakhov Nov 6, 2024
a56e94b
tests: remove imports that were deprecated in Python 3.9 (#8643)
SpecLad Nov 6, 2024
148a572
Bump the patch version after each release, not the minor (#7179)
SpecLad Nov 7, 2024
ac20ed2
Fixed: Cannot read properties of undefined (reading 'push') (#8648)
bsekachev Nov 7, 2024
7f764a2
Fixed incorrect imports (#8654)
bsekachev Nov 7, 2024
e2b2a51
Remove gratuitous non-ASCII characters (#7683)
SpecLad Nov 7, 2024
beb8925
Ignore not relevant tasks/projects/jobs responses (#8653)
bsekachev Nov 7, 2024
1f3fbb9
Add a quality setting for avoiding using bbox in point group matching…
zhiltsov-max Nov 7, 2024
1fd1175
Fixed: Re-newed import/export request failed immediately if the previ…
bsekachev Nov 7, 2024
53a84c8
Fixed automatic zooming in attribute annotation mode for masks (#8657)
bsekachev Nov 7, 2024
58775bf
Increased maximum length of displayed error message (#8658)
bsekachev Nov 7, 2024
a6fd1e5
Export dataset in CVAT format misses frames in tasks with non-default…
bsekachev Nov 8, 2024
e202225
Fix: Progress on Requets page is displayed as `0..1` (#8668)
klakhov Nov 11, 2024
ed33852
Merge the notifications and cleaning workers (#8672)
SpecLad Nov 11, 2024
d315485
Allow matching empty frames in quality checks (#8652)
zhiltsov-max Nov 11, 2024
333df35
Prepare release v2.22.0
cvat-bot[bot] Nov 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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/changed-files@v41.0.0
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 @@
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 @@
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 @@
});
}

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) {

Check warning on line 1311 in cvat-canvas/src/typescript/drawHandler.ts

View workflow job for this annotation

GitHub Actions / Linter

Missing return type on function
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 @@
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 @@
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 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 @@
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 @@
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) {

Check warning on line 229 in cvat-canvas/src/typescript/masksHandler.ts

View workflow job for this annotation

GitHub Actions / Linter

Missing return type on function
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 @@
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 @@
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 @@

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 @@
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 @@
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
Loading