Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/zm/compare-point-groups-in-image…
Browse files Browse the repository at this point in the history
…-space' into zm/compare-point-groups-in-image-space
  • Loading branch information
zhiltsov-max committed Nov 1, 2024
2 parents 1f53477 + af6e862 commit 303375c
Show file tree
Hide file tree
Showing 132 changed files with 1,147 additions and 771 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/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 .
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

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

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

### Changed

- CLI no longer prints the stack trace in case of HTTP errors
(<https://github.com/cvat-ai/cvat/pull/8601>)

### Removed

- Dropped support for Python 3.8 since its EOL was on 2024-10-07
(<https://github.com/cvat-ai/cvat/pull/8360>)

### Fixed

- Requests page crush with `Cannot read property 'target' of undefined` error
(<https://github.com/cvat-ai/cvat/pull/8575>)

- Tags in ground truth job were displayed as `tag (GT)`
(<https://github.com/cvat-ai/cvat/pull/8586>)

- Tags in ground truth job couldn't be deleted via `x` button
(<https://github.com/cvat-ai/cvat/pull/8586>)

- Exception 'Canvas is busy' when change frame during drag/resize a track
(<https://github.com/cvat-ai/cvat/pull/8598>)

- A shape gets shifted if auto save triggered during dragging
(<https://github.com/cvat-ai/cvat/pull/8598>)

<a id='changelog-2.21.2'></a>
## \[2.21.2\] - 2024-10-24

Expand Down
3 changes: 3 additions & 0 deletions changelog.d/20241018_142148_klakhov_hide_mask.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Added

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

This file was deleted.

7 changes: 0 additions & 7 deletions changelog.d/20241023_120236_klakhov_improve_gt_tags.md

This file was deleted.

4 changes: 0 additions & 4 deletions changelog.d/20241028_140908_sekachev.bs.md

This file was deleted.

4 changes: 0 additions & 4 deletions changelog.d/20241028_140945_sekachev.bs.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
### Fixed

- Exporting projects with tasks containing honeypots. Honeypots are no longer exported.
(<https://github.com/cvat-ai/cvat/pull/8597>)
4 changes: 0 additions & 4 deletions changelog.d/20241029_113229_maria_drop_python_3_8_support.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
### Removed

- Removed unused business group
(<https://github.com/cvat-ai/cvat/pull/8607>)
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
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) {

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

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 @@ 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
3 changes: 2 additions & 1 deletion cvat-cli/src/cvat_cli/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from types import SimpleNamespace
from typing import List

import urllib3.exceptions
from cvat_sdk import exceptions
from cvat_sdk.core.client import Client, Config

Expand Down Expand Up @@ -70,7 +71,7 @@ def main(args: List[str] = None):
try:
cli = CLI(client=client, credentials=parsed_args.auth)
actions[parsed_args.action](cli, **vars(action_args))
except exceptions.ApiException as e:
except (exceptions.ApiException, urllib3.exceptions.HTTPError) as e:
logger.critical(e)
return 1

Expand Down
Loading

0 comments on commit 303375c

Please sign in to comment.