Skip to content

Commit

Permalink
Merge branch 'develop' into dk/project-import-prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikita Manovich committed Dec 16, 2021
2 parents 285d2d0 + cde33ac commit 4a50366
Show file tree
Hide file tree
Showing 25 changed files with 366 additions and 62 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Options to change font size & position of text labels on the canvas (<https://github.com/openvinotoolkit/cvat/pull/3972>)
- Add "tag" return type for automatic annotation in Nuclio (<https://github.com/openvinotoolkit/cvat/pull/3896>)
- Dataset importing to a project (<https://github.com/openvinotoolkit/cvat/pull/3790>)
- User is able to customize information that text labels show (<https://github.com/openvinotoolkit/cvat/pull/4029>)

### Changed
- TDB
Expand All @@ -40,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed task creating with large files via webpage (<https://github.com/openvinotoolkit/cvat/pull/3692>)
- Added information to export CVAT_HOST when performing local installation for accessing over network (<https://github.com/openvinotoolkit/cvat/pull/4014>)
- Fixed possible color collisions in the generated colormap (<https://github.com/openvinotoolkit/cvat/pull/4007>)
- Original pdf file is deleted when using share(<https://github.com/openvinotoolkit/cvat/pull/3967>)

### Security
- TDB
Expand Down
6 changes: 3 additions & 3 deletions components/analytics/docker-compose.analytics.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ services:
build:
context: ./components/analytics/elasticsearch
args:
ELK_VERSION: 6.4.0
ELK_VERSION: 6.8.21
volumes:
- cvat_events:/usr/share/elasticsearch/data
restart: always
Expand All @@ -21,7 +21,7 @@ services:
build:
context: ./components/analytics/kibana
args:
ELK_VERSION: 6.4.0
ELK_VERSION: 6.8.21
depends_on: ['elasticsearch']
restart: always

Expand Down Expand Up @@ -62,7 +62,7 @@ services:
build:
context: ./components/analytics/logstash
args:
ELK_VERSION: 6.4.0
ELK_VERSION: 6.8.21
http_proxy: ${http_proxy}
https_proxy: ${https_proxy}
environment:
Expand Down
27 changes: 24 additions & 3 deletions components/analytics/kibana/setup.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# Copyright (C) 2021 Intel Corporation
#
# SPDX-License-Identifier: MIT

#/usr/bin/env python

import os
import argparse
import requests
import json
from time import sleep
import requests

def import_resources(host, port, cfg_file):
with open(cfg_file, 'r') as f:
Expand All @@ -27,6 +31,19 @@ def import_saved_object(host, port, _type, _id, data):
headers={'kbn-xsrf': 'true'})
request.raise_for_status()

def wait_for_status(host, port, status='green', max_attempts=10, delay=3):
for _ in range(max_attempts):
response = requests.get('http://{}:{}/api/status'.format(host, port))
if response.status_code != 200:
sleep(delay)
continue

response = response.json()
if status == response['status']['overall']['state']:
return True

return False

if __name__ == '__main__':
parser = argparse.ArgumentParser(description='import Kibana 6.x resources',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
Expand All @@ -37,4 +54,8 @@ def import_saved_object(host, port, _type, _id, data):
parser.add_argument('-H', '--host', metavar='HOST', default='kibana',
help='host of Kibana instance')
args = parser.parse_args()
import_resources(args.host, args.port, args.export_file)

if wait_for_status(args.host, args.port):
import_resources(args.host, args.port, args.export_file)
else:
exit('Cannot setup Kibana objects')
4 changes: 2 additions & 2 deletions 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.10.1",
"version": "2.11.0",
"description": "Part of Computer Vision Annotation Tool which presents its canvas library",
"main": "src/canvas.ts",
"scripts": {
Expand Down
14 changes: 13 additions & 1 deletion cvat-canvas/src/typescript/canvasModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//
// SPDX-License-Identifier: MIT

import consts from './consts';
import { MasterImpl } from './master';

export interface Size {
Expand Down Expand Up @@ -57,6 +58,7 @@ export interface Configuration {
displayAllText?: boolean;
textFontSize?: number;
textPosition?: 'auto' | 'center';
textContent?: string;
undefinedAttrValue?: string;
showProjections?: boolean;
forceDisableEditing?: boolean;
Expand Down Expand Up @@ -263,6 +265,9 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
displayAllText: false,
autoborders: false,
undefinedAttrValue: '',
textContent: 'id,label,attributes,source,descriptions',
textPosition: 'auto',
textFontSize: consts.DEFAULT_SHAPE_TEXT_SIZE,
},
imageBitmap: false,
image: null,
Expand Down Expand Up @@ -649,14 +654,21 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
this.data.configuration.displayAllText = configuration.displayAllText;
}

if (typeof configuration.textFontSize === 'number') {
if (typeof configuration.textFontSize === 'number' && configuration.textFontSize >= consts.MINIMUM_TEXT_FONT_SIZE) {
this.data.configuration.textFontSize = configuration.textFontSize;
}

if (['auto', 'center'].includes(configuration.textPosition)) {
this.data.configuration.textPosition = configuration.textPosition;
}

if (typeof configuration.textContent === 'string') {
const splitted = configuration.textContent.split(',').filter((entry: string) => !!entry);
if (splitted.every((entry: string) => ['id', 'label', 'attributes', 'source', 'descriptions'].includes(entry))) {
this.data.configuration.textContent = configuration.textContent;
}
}

if (typeof configuration.showProjections === 'boolean') {
this.data.configuration.showProjections = configuration.showProjections;
}
Expand Down
75 changes: 50 additions & 25 deletions cvat-canvas/src/typescript/canvasView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1189,9 +1189,11 @@ export class CanvasViewImpl implements CanvasView, Listener {
}
}

const recreateText = configuration.textContent !== this.configuration.textContent;
const updateTextPosition = configuration.displayAllText !== this.configuration.displayAllText ||
configuration.textFontSize !== this.configuration.textFontSize ||
configuration.textPosition !== this.configuration.textPosition;
configuration.textPosition !== this.configuration.textPosition ||
recreateText;

if (configuration.smoothImage === true) {
this.background.classList.remove('cvat_canvas_pixelized');
Expand All @@ -1200,6 +1202,19 @@ export class CanvasViewImpl implements CanvasView, Listener {
}

this.configuration = configuration;
if (recreateText) {
const states = this.controller.objects;
for (const key of Object.keys(this.drawnStates)) {
const clientID = +key;
const [state] = states.filter((_state: any) => _state.clientID === clientID);
if (clientID in this.svgTexts) {
this.svgTexts[clientID].remove();
delete this.svgTexts[clientID];
if (state) this.svgTexts[clientID] = this.addText(state);
}
}
}

if (updateTextPosition) {
for (const i in this.drawnStates) {
if (i in this.svgTexts) {
Expand Down Expand Up @@ -2071,11 +2086,10 @@ export class CanvasViewImpl implements CanvasView, Listener {
// Update text position after corresponding box has been moved, resized, etc.
private updateTextPosition(text: SVG.Text, shape: SVG.Shape): void {
if (text.node.style.display === 'none') return; // wrong transformation matrix
const textFontSize = this.configuration.textFontSize || consts.DEFAULT_SHAPE_TEXT_SIZE;
const textPosition = this.configuration.textPosition || 'auto';
const { textFontSize, textPosition } = this.configuration;

text.untransform();
text.style({ 'font-size': textFontSize });
text.style({ 'font-size': `${textFontSize}px` });
const { rotation } = shape.transform();

// Find the best place for a text
Expand Down Expand Up @@ -2131,8 +2145,8 @@ export class CanvasViewImpl implements CanvasView, Listener {

// Translate found coordinates to text SVG
const [x, y, rotX, rotY]: number[] = translateToSVG(this.text, [
clientX + consts.TEXT_MARGIN,
clientY + consts.TEXT_MARGIN,
clientX + (textPosition === 'auto' ? consts.TEXT_MARGIN : 0),
clientY + (textPosition === 'auto' ? consts.TEXT_MARGIN : 0),
clientCX,
clientCY,
]);
Expand All @@ -2156,6 +2170,13 @@ export class CanvasViewImpl implements CanvasView, Listener {

private addText(state: any): SVG.Text {
const { undefinedAttrValue } = this.configuration;
const content = this.configuration.textContent;
const withID = content.includes('id');
const withAttr = content.includes('attributes');
const withLabel = content.includes('label');
const withSource = content.includes('source');
const withDescriptions = content.includes('descriptions');

const textFontSize = this.configuration.textFontSize || 12;
const {
label, clientID, attributes, source, descriptions,
Expand All @@ -2167,28 +2188,32 @@ export class CanvasViewImpl implements CanvasView, Listener {

return this.adoptedText
.text((block): void => {
block.tspan(`${label.name} ${clientID} (${source})`).style({
block.tspan(`${withLabel ? label.name : ''} ${withID ? clientID : ''} ${withSource ? `(${source})` : ''}`).style({
'text-transform': 'uppercase',
});
for (const desc of descriptions) {
block
.tspan(`${desc}`)
.attr({
dy: '1em',
x: 0,
})
.addClass('cvat_canvas_text_description');
if (withDescriptions) {
for (const desc of descriptions) {
block
.tspan(`${desc}`)
.attr({
dy: '1em',
x: 0,
})
.addClass('cvat_canvas_text_description');
}
}
for (const attrID of Object.keys(attributes)) {
const value = attributes[attrID] === undefinedAttrValue ? '' : attributes[attrID];
block
.tspan(`${attrNames[attrID]}: ${value}`)
.attr({
attrID,
dy: '1em',
x: 0,
})
.addClass('cvat_canvas_text_attribute');
if (withAttr) {
for (const attrID of Object.keys(attributes)) {
const value = attributes[attrID] === undefinedAttrValue ? '' : attributes[attrID];
block
.tspan(`${attrNames[attrID]}: ${value}`)
.attr({
attrID,
dy: '1em',
x: 0,
})
.addClass('cvat_canvas_text_attribute');
}
}
})
.move(0, 0)
Expand Down
2 changes: 2 additions & 0 deletions cvat-canvas/src/typescript/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const BASE_PATTERN_SIZE = 5;
const SNAP_TO_ANGLE_RESIZE_DEFAULT = 0.1;
const SNAP_TO_ANGLE_RESIZE_SHIFT = 15;
const DEFAULT_SHAPE_TEXT_SIZE = 12;
const MINIMUM_TEXT_FONT_SIZE = 8;

export default {
BASE_STROKE_WIDTH,
Expand All @@ -39,4 +40,5 @@ export default {
SNAP_TO_ANGLE_RESIZE_DEFAULT,
SNAP_TO_ANGLE_RESIZE_SHIFT,
DEFAULT_SHAPE_TEXT_SIZE,
MINIMUM_TEXT_FONT_SIZE,
};
4 changes: 2 additions & 2 deletions cvat-ui/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-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cvat-ui",
"version": "1.28.2",
"version": "1.29.0",
"description": "CVAT single-page application",
"main": "src/index.tsx",
"scripts": {
Expand Down
10 changes: 10 additions & 0 deletions cvat-ui/src/actions/settings-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export enum SettingsActionTypes {
SWITCH_SMOOTH_IMAGE = 'SWITCH_SMOOTH_IMAGE',
SWITCH_TEXT_FONT_SIZE = 'SWITCH_TEXT_FONT_SIZE',
SWITCH_TEXT_POSITION = 'SWITCH_TEXT_POSITION',
SWITCH_TEXT_CONTENT = 'SWITCH_TEXT_CONTENT',
CHANGE_BRIGHTNESS_LEVEL = 'CHANGE_BRIGHTNESS_LEVEL',
CHANGE_CONTRAST_LEVEL = 'CHANGE_CONTRAST_LEVEL',
CHANGE_SATURATION_LEVEL = 'CHANGE_SATURATION_LEVEL',
Expand Down Expand Up @@ -196,6 +197,15 @@ export function switchTextPosition(position: 'auto' | 'center'): AnyAction {
};
}

export function switchTextContent(textContent: string): AnyAction {
return {
type: SettingsActionTypes.SWITCH_TEXT_CONTENT,
payload: {
textContent,
},
};
}

export function changeBrightnessLevel(level: number): AnyAction {
return {
type: SettingsActionTypes.CHANGE_BRIGHTNESS_LEVEL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ interface Props {
showObjectsTextAlways: boolean;
textFontSize: number;
textPosition: 'auto' | 'center';
textContent: string;
showAllInterpolationTracks: boolean;
workspace: Workspace;
automaticBordering: boolean;
Expand Down Expand Up @@ -111,6 +112,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
smoothImage,
textFontSize,
textPosition,
textContent,
} = this.props;
const { canvasInstance } = this.props as { canvasInstance: Canvas };

Expand All @@ -130,6 +132,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
creationOpacity: selectedOpacity,
textFontSize,
textPosition,
textContent,
});

this.initialSetup();
Expand Down Expand Up @@ -166,6 +169,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
showObjectsTextAlways,
textFontSize,
textPosition,
textContent,
showAllInterpolationTracks,
automaticBordering,
intelligentPolygonCrop,
Expand All @@ -182,7 +186,8 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
prevProps.selectedOpacity !== selectedOpacity ||
prevProps.smoothImage !== smoothImage ||
prevProps.textFontSize !== textFontSize ||
prevProps.textPosition !== textPosition
prevProps.textPosition !== textPosition ||
prevProps.textContent !== textContent
) {
canvasInstance.configure({
undefinedAttrValue: consts.UNDEFINED_ATTRIBUTE_VALUE,
Expand All @@ -194,6 +199,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
smoothImage,
textFontSize,
textPosition,
textContent,
});
}

Expand Down
Loading

0 comments on commit 4a50366

Please sign in to comment.