Using serverside paremeter min_pos_points, right colors of labels in … (#2162)

* Using serverside paremeter min_pos_points, right colors of labels in detector runner

* Updated changelog & versions

* Using color from consts instead of literal
main
Boris Sekachev 6 years ago committed by GitHub
parent a2997960c3
commit b71e77b17b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- UI models (like DEXTR) were redesigned to be more interactive (<https://github.com/opencv/cvat/pull/2054>) - UI models (like DEXTR) were redesigned to be more interactive (<https://github.com/opencv/cvat/pull/2054>)
- Used Ubuntu:20.04 as a base image for CVAT Dockerfile (<https://github.com/opencv/cvat/pull/2101>) - Used Ubuntu:20.04 as a base image for CVAT Dockerfile (<https://github.com/opencv/cvat/pull/2101>)
- Right colors of label tags in label mapping when a user runs automatic detection (<https://github.com/openvinotoolkit/cvat/pull/2162>)
### Deprecated ### Deprecated
- -

@ -1,6 +1,6 @@
{ {
"name": "cvat-core", "name": "cvat-core",
"version": "3.6.1", "version": "3.7.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

@ -1,6 +1,6 @@
{ {
"name": "cvat-core", "name": "cvat-core",
"version": "3.6.1", "version": "3.7.0",
"description": "Part of Computer Vision Tool which presents an interface for client-side integration", "description": "Part of Computer Vision Tool which presents an interface for client-side integration",
"main": "babel.config.js", "main": "babel.config.js",
"scripts": { "scripts": {

@ -29,11 +29,7 @@ class LambdaManager {
for (const model of result) { for (const model of result) {
models.push(new MLModel({ models.push(new MLModel({
id: model.id, ...model,
name: model.name,
description: model.description,
framework: model.framework,
labels: [...model.labels],
type: model.kind, type: model.kind,
})); }));
} }

@ -15,6 +15,11 @@ class MLModel {
this._framework = data.framework; this._framework = data.framework;
this._description = data.description; this._description = data.description;
this._type = data.type; this._type = data.type;
this._params = {
canvas: {
minPosVertices: data.min_pos_points,
},
};
} }
/** /**
@ -68,6 +73,16 @@ class MLModel {
get type() { get type() {
return this._type; return this._type;
} }
/**
* @returns {object}
* @readonly
*/
get params() {
return {
canvas: { ...this._params.canvas },
};
}
} }
module.exports = MLModel; module.exports = MLModel;

@ -1,6 +1,6 @@
{ {
"name": "cvat-ui", "name": "cvat-ui",
"version": "1.9.3", "version": "1.9.4",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

@ -1,6 +1,6 @@
{ {
"name": "cvat-ui", "name": "cvat-ui",
"version": "1.9.3", "version": "1.9.4",
"description": "CVAT single-page application", "description": "CVAT single-page application",
"main": "src/index.tsx", "main": "src/index.tsx",
"scripts": { "scripts": {

@ -1446,7 +1446,7 @@ export function repeatDrawShapeAsync(): ThunkAction {
canvasInstance.interact({ canvasInstance.interact({
enabled: true, enabled: true,
shapeType: 'points', shapeType: 'points',
minPosVertices: 4, // TODO: Add parameter to interactor ...activeInteractor.params.canvas,
}); });
dispatch(interactWithCanvas(activeInteractor, activeLabelID)); dispatch(interactWithCanvas(activeInteractor, activeLabelID));
} }

@ -657,8 +657,8 @@ export class ToolsControlComponent extends React.PureComponent<Props, State> {
canvasInstance.cancel(); canvasInstance.cancel();
canvasInstance.interact({ canvasInstance.interact({
shapeType: 'points', shapeType: 'points',
minPosVertices: 4, // TODO: Add parameter to interactor
enabled: true, enabled: true,
...activeInteractor.params.canvas,
}); });
onInteractionStart(activeInteractor, activeLabelID); onInteractionStart(activeInteractor, activeLabelID);

@ -10,34 +10,15 @@ import Select, { OptionProps } from 'antd/lib/select';
import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox'; import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox';
import Tooltip from 'antd/lib/tooltip'; import Tooltip from 'antd/lib/tooltip';
import Tag from 'antd/lib/tag'; import Tag from 'antd/lib/tag';
import notification from 'antd/lib/notification';
import Text from 'antd/lib/typography/Text'; import Text from 'antd/lib/typography/Text';
import InputNumber from 'antd/lib/input-number'; import InputNumber from 'antd/lib/input-number';
import { Model, StringObject } from 'reducers/interfaces';
import Button from 'antd/lib/button'; import Button from 'antd/lib/button';
import notification from 'antd/lib/notification';
import { Model, StringObject } from 'reducers/interfaces';
function colorGenerator(): () => string {
const values = [
'magenta', 'green', 'geekblue',
'orange', 'red', 'cyan',
'blue', 'volcano', 'purple',
];
let index = 0;
return (): string => {
const color = values[index++];
if (index >= values.length) {
index = 0;
}
return color;
};
}
const nextColor = colorGenerator(); import consts from 'consts';
interface Props { interface Props {
withCleanup: boolean; withCleanup: boolean;
@ -56,7 +37,6 @@ function DetectorRunner(props: Props): JSX.Element {
const [modelID, setModelID] = useState<string | null>(null); const [modelID, setModelID] = useState<string | null>(null);
const [mapping, setMapping] = useState<StringObject>({}); const [mapping, setMapping] = useState<StringObject>({});
const [colors, setColors] = useState<StringObject>({});
const [threshold, setThreshold] = useState<number>(0.5); const [threshold, setThreshold] = useState<number>(0.5);
const [distance, setDistance] = useState<number>(50); const [distance, setDistance] = useState<number>(50);
const [cleanup, setCleanup] = useState<boolean>(false); const [cleanup, setCleanup] = useState<boolean>(false);
@ -90,10 +70,7 @@ function DetectorRunner(props: Props): JSX.Element {
function updateMatch(modelLabel: string | null, taskLabel: string | null): void { function updateMatch(modelLabel: string | null, taskLabel: string | null): void {
if (match.model && taskLabel) { if (match.model && taskLabel) {
const newmatch: { [index: string]: string } = {}; const newmatch: { [index: string]: string } = {};
const newcolor: { [index: string]: string } = {};
newmatch[match.model] = taskLabel; newmatch[match.model] = taskLabel;
newcolor[match.model] = nextColor();
setColors({ ...colors, ...newcolor });
setMapping({ ...mapping, ...newmatch }); setMapping({ ...mapping, ...newmatch });
setMatch({ model: null, task: null }); setMatch({ model: null, task: null });
return; return;
@ -101,10 +78,7 @@ function DetectorRunner(props: Props): JSX.Element {
if (match.task && modelLabel) { if (match.task && modelLabel) {
const newmatch: { [index: string]: string } = {}; const newmatch: { [index: string]: string } = {};
const newcolor: { [index: string]: string } = {};
newmatch[modelLabel] = match.task; newmatch[modelLabel] = match.task;
newcolor[modelLabel] = nextColor();
setColors({ ...colors, ...newcolor });
setMapping({ ...mapping, ...newmatch }); setMapping({ ...mapping, ...newmatch });
setMatch({ model: null, task: null }); setMatch({ model: null, task: null });
return; return;
@ -157,18 +131,15 @@ function DetectorRunner(props: Props): JSX.Element {
onChange={(_modelID: string): void => { onChange={(_modelID: string): void => {
const newmodel = models const newmodel = models
.filter((_model): boolean => _model.id === _modelID)[0]; .filter((_model): boolean => _model.id === _modelID)[0];
const newcolors: StringObject = {};
const newmapping = task.labels const newmapping = task.labels
.reduce((acc: StringObject, label: any): StringObject => { .reduce((acc: StringObject, label: any): StringObject => {
if (newmodel.labels.includes(label.name)) { if (newmodel.labels.includes(label.name)) {
acc[label.name] = label.name; acc[label.name] = label.name;
newcolors[label.name] = nextColor();
} }
return acc; return acc;
}, {}); }, {});
setMapping(newmapping); setMapping(newmapping);
setColors(newcolors);
setMatch({ model: null, task: null }); setMatch({ model: null, task: null });
setModelID(_modelID); setModelID(_modelID);
}} }}
@ -180,29 +151,34 @@ function DetectorRunner(props: Props): JSX.Element {
</Col> </Col>
</Row> </Row>
{ isDetector && !!Object.keys(mapping).length && ( { isDetector && !!Object.keys(mapping).length && (
Object.keys(mapping).map((modelLabel: string) => ( Object.keys(mapping).map((modelLabel: string) => {
<Row key={modelLabel} type='flex' justify='start' align='middle'> const label = task.labels
<Col span={10}> .filter((_label: any): boolean => _label.name === mapping[modelLabel])[0];
<Tag color={colors[modelLabel]}>{modelLabel}</Tag> const color = label ? label.color : consts.NEW_LABEL_COLOR;
</Col> return (
<Col span={10} offset={1}> <Row key={modelLabel} type='flex' justify='start' align='middle'>
<Tag color={colors[modelLabel]}>{mapping[modelLabel]}</Tag> <Col span={10}>
</Col> <Tag color={color}>{modelLabel}</Tag>
<Col offset={1}> </Col>
<Tooltip title='Remove the mapped values' mouseLeaveDelay={0}> <Col span={10} offset={1}>
<Icon <Tag color={color}>{mapping[modelLabel]}</Tag>
className='cvat-danger-circle-icon' </Col>
type='close-circle' <Col offset={1}>
onClick={(): void => { <Tooltip title='Remove the mapped values' mouseLeaveDelay={0}>
const newmapping = { ...mapping }; <Icon
delete newmapping[modelLabel]; className='cvat-danger-circle-icon'
setMapping(newmapping); type='close-circle'
}} onClick={(): void => {
/> const newmapping = { ...mapping };
</Tooltip> delete newmapping[modelLabel];
</Col> setMapping(newmapping);
</Row> }}
)) />
</Tooltip>
</Col>
</Row>
);
})
)} )}
{ isDetector && !!taskLabels.length && !!modelLabels.length && ( { isDetector && !!taskLabels.length && !!modelLabels.length && (
<> <>

@ -141,6 +141,9 @@ export interface Model {
framework: string; framework: string;
description: string; description: string;
type: string; type: string;
params: {
canvas: object;
};
} }
export enum RQStatus { export enum RQStatus {

@ -109,6 +109,7 @@ class LambdaFunction:
self.framework = data['metadata']['annotations'].get('framework') self.framework = data['metadata']['annotations'].get('framework')
# display name for the function # display name for the function
self.name = data['metadata']['annotations'].get('name', self.id) self.name = data['metadata']['annotations'].get('name', self.id)
self.min_pos_points = int(data['metadata']['annotations'].get('min_pos_points', 1))
self.gateway = gateway self.gateway = gateway
def to_dict(self): def to_dict(self):
@ -120,6 +121,7 @@ class LambdaFunction:
'description': self.description, 'description': self.description,
'framework': self.framework, 'framework': self.framework,
'name': self.name, 'name': self.name,
'min_pos_points': self.min_pos_points
} }
return response return response

Loading…
Cancel
Save