Added automatic annotation progress to the task view (#2148)

* Added automatic annotation progress to the task view

* Updated changelog & version

Co-authored-by: Nikita Manovich <nikita.manovich@intel.com>
main
Boris Sekachev 6 years ago committed by GitHub
parent 8d3c95a764
commit 38acc99f27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Ability to work with data on the fly (https://github.com/opencv/cvat/pull/2007) - Ability to work with data on the fly (https://github.com/opencv/cvat/pull/2007)
- Annotation in process outline color wheel (<https://github.com/opencv/cvat/pull/2084>) - Annotation in process outline color wheel (<https://github.com/opencv/cvat/pull/2084>)
- On the fly annotation using DL detectors (<https://github.com/opencv/cvat/pull/2102>) - On the fly annotation using DL detectors (<https://github.com/opencv/cvat/pull/2102>)
- Displaying automatic annotation progress on a task view (<https://github.com/opencv/cvat/pull/2148>)
- Automatic tracking of bounding boxes using serverless functions (<https://github.com/opencv/cvat/pull/2136>) - Automatic tracking of bounding boxes using serverless functions (<https://github.com/opencv/cvat/pull/2136>)
- [Datumaro] CLI command for dataset equality comparison (<https://github.com/opencv/cvat/pull/1989>) - [Datumaro] CLI command for dataset equality comparison (<https://github.com/opencv/cvat/pull/1989>)
- [Datumaro] Merging of datasets with different labels (<https://github.com/opencv/cvat/pull/2098>) - [Datumaro] Merging of datasets with different labels (<https://github.com/opencv/cvat/pull/2098>)

@ -16,6 +16,8 @@ import moment from 'moment';
import getCore from 'cvat-core-wrapper'; import getCore from 'cvat-core-wrapper';
import patterns from 'utils/validation-patterns'; import patterns from 'utils/validation-patterns';
import { getReposData, syncRepos } from 'utils/git-utils'; import { getReposData, syncRepos } from 'utils/git-utils';
import { ActiveInference } from 'reducers/interfaces';
import AutomaticAnnotationProgress from 'components/tasks-page/automatic-annotation-progress';
import UserSelector from './user-selector'; import UserSelector from './user-selector';
import LabelsEditorComponent from '../labels-editor/labels-editor'; import LabelsEditorComponent from '../labels-editor/labels-editor';
@ -26,6 +28,8 @@ interface Props {
taskInstance: any; taskInstance: any;
installedGit: boolean; // change to git repos url installedGit: boolean; // change to git repos url
registeredUsers: any[]; registeredUsers: any[];
activeInference: ActiveInference | null;
cancelAutoAnnotation(): void;
onTaskUpdate: (taskInstance: any) => void; onTaskUpdate: (taskInstance: any) => void;
} }
@ -125,10 +129,7 @@ export default class DetailsComponent extends React.PureComponent<Props, State>
private renderTaskName(): JSX.Element { private renderTaskName(): JSX.Element {
const { name } = this.state; const { name } = this.state;
const { const { taskInstance, onTaskUpdate } = this.props;
taskInstance,
onTaskUpdate,
} = this.props;
return ( return (
<Title <Title
@ -161,9 +162,7 @@ export default class DetailsComponent extends React.PureComponent<Props, State>
private renderParameters(): JSX.Element { private renderParameters(): JSX.Element {
const { taskInstance } = this.props; const { taskInstance } = this.props;
const { overlap } = taskInstance; const { overlap, segmentSize, imageQuality } = taskInstance;
const { segmentSize } = taskInstance;
const { imageQuality } = taskInstance;
const zOrder = taskInstance.zOrder.toString(); const zOrder = taskInstance.zOrder.toString();
return ( return (
@ -197,11 +196,7 @@ export default class DetailsComponent extends React.PureComponent<Props, State>
} }
private renderUsers(): JSX.Element { private renderUsers(): JSX.Element {
const { const { taskInstance, registeredUsers, onTaskUpdate } = this.props;
taskInstance,
registeredUsers,
onTaskUpdate,
} = this.props;
const owner = taskInstance.owner ? taskInstance.owner.username : null; const owner = taskInstance.owner ? taskInstance.owner.username : null;
const assignee = taskInstance.assignee ? taskInstance.assignee.username : null; const assignee = taskInstance.assignee ? taskInstance.assignee.username : null;
const created = moment(taskInstance.createdDate).format('MMMM Do YYYY'); const created = moment(taskInstance.createdDate).format('MMMM Do YYYY');
@ -246,10 +241,7 @@ export default class DetailsComponent extends React.PureComponent<Props, State>
private renderDatasetRepository(): JSX.Element | boolean { private renderDatasetRepository(): JSX.Element | boolean {
const { taskInstance } = this.props; const { taskInstance } = this.props;
const { const { repository, repositoryStatus } = this.state;
repository,
repositoryStatus,
} = this.state;
return ( return (
!!repository !!repository
@ -321,10 +313,7 @@ export default class DetailsComponent extends React.PureComponent<Props, State>
} }
private renderBugTracker(): JSX.Element { private renderBugTracker(): JSX.Element {
const { const { taskInstance, onTaskUpdate } = this.props;
taskInstance,
onTaskUpdate,
} = this.props;
const { bugTracker, bugTrackerEditing } = this.state; const { bugTracker, bugTrackerEditing } = this.state;
let shown = false; let shown = false;
@ -400,10 +389,7 @@ export default class DetailsComponent extends React.PureComponent<Props, State>
} }
private renderLabelsEditor(): JSX.Element { private renderLabelsEditor(): JSX.Element {
const { const { taskInstance, onTaskUpdate } = this.props;
taskInstance,
onTaskUpdate,
} = this.props;
return ( return (
<Row> <Row>
@ -424,6 +410,7 @@ export default class DetailsComponent extends React.PureComponent<Props, State>
} }
public render(): JSX.Element { public render(): JSX.Element {
const { activeInference, cancelAutoAnnotation } = this.props;
return ( return (
<div className='cvat-task-details'> <div className='cvat-task-details'>
<Row type='flex' justify='start' align='middle'> <Row type='flex' justify='start' align='middle'>
@ -446,7 +433,17 @@ export default class DetailsComponent extends React.PureComponent<Props, State>
</Col> </Col>
<Col md={16} lg={17} xl={17} xxl={18}> <Col md={16} lg={17} xl={17} xxl={18}>
{ this.renderUsers() } { this.renderUsers() }
{ this.renderBugTracker() } <Row type='flex' justify='space-between' align='middle'>
<Col span={12}>
{ this.renderBugTracker() }
</Col>
<Col span={10}>
<AutomaticAnnotationProgress
activeInference={activeInference}
cancelAutoAnnotation={cancelAutoAnnotation}
/>
</Col>
</Row>
{ this.renderDatasetRepository() } { this.renderDatasetRepository() }
{ this.renderLabelsEditor() } { this.renderLabelsEditor() }
</Col> </Col>

@ -0,0 +1,63 @@
// Copyright (C) 2020 Intel Corporation
//
// SPDX-License-Identifier: MIT
import React from 'react';
import { Row, Col } from 'antd/lib/grid';
import Text from 'antd/lib/typography/Text';
import Progress from 'antd/lib/progress';
import Tooltip from 'antd/lib/tooltip';
import Icon from 'antd/lib/icon';
import Modal from 'antd/lib/modal';
import { ActiveInference } from 'reducers/interfaces';
interface Props {
activeInference: ActiveInference | null;
cancelAutoAnnotation(): void;
}
export default function AutomaticAnnotationProgress(props: Props): JSX.Element | null {
const { activeInference, cancelAutoAnnotation } = props;
if (!activeInference) return null;
return (
<>
<Row>
<Col>
<Text strong>Automatic annotation</Text>
</Col>
</Row>
<Row type='flex' justify='space-between'>
<Col span={22}>
<Progress
percent={Math.floor(activeInference.progress)}
strokeColor={{
from: '#108ee9',
to: '#87d068',
}}
showInfo={false}
strokeWidth={5}
size='small'
/>
</Col>
<Col span={1} className='close-auto-annotation-icon'>
<Tooltip title='Cancel automatic annotation' mouseLeaveDelay={0}>
<Icon
type='close'
onClick={() => {
Modal.confirm({
title: 'You are going to cancel automatic annotation?',
content: 'Reached progress will be lost. Continue?',
okType: 'danger',
onOk() {
cancelAutoAnnotation();
},
});
}}
/>
</Tooltip>
</Col>
</Row>
</>
);
}

@ -10,14 +10,13 @@ import { Row, Col } from 'antd/lib/grid';
import Button from 'antd/lib/button'; import Button from 'antd/lib/button';
import Icon from 'antd/lib/icon'; import Icon from 'antd/lib/icon';
import Dropdown from 'antd/lib/dropdown'; import Dropdown from 'antd/lib/dropdown';
import Tooltip from 'antd/lib/tooltip';
import Modal from 'antd/lib/modal';
import Progress from 'antd/lib/progress'; import Progress from 'antd/lib/progress';
import moment from 'moment'; import moment from 'moment';
import ActionsMenuContainer from 'containers/actions-menu/actions-menu'; import ActionsMenuContainer from 'containers/actions-menu/actions-menu';
import { ActiveInference } from 'reducers/interfaces'; import { ActiveInference } from 'reducers/interfaces';
import { MenuIcon } from 'icons'; import { MenuIcon } from 'icons';
import AutomaticAnnotationProgress from './automatic-annotation-progress';
export interface TaskItemProps { export interface TaskItemProps {
taskInstance: any; taskInstance: any;
@ -123,47 +122,10 @@ class TaskItemComponent extends React.PureComponent<TaskItemProps & RouteCompone
/> />
</Col> </Col>
</Row> </Row>
{ activeInference <AutomaticAnnotationProgress
&& ( activeInference={activeInference}
<> cancelAutoAnnotation={cancelAutoAnnotation}
<Row> />
<Col>
<Text strong>Automatic annotation</Text>
</Col>
</Row>
<Row type='flex' justify='space-between'>
<Col span={22}>
<Progress
percent={Math.floor(activeInference.progress)}
strokeColor={{
from: '#108ee9',
to: '#87d068',
}}
showInfo={false}
strokeWidth={5}
size='small'
/>
</Col>
<Col span={1} className='close-auto-annotation-icon'>
<Tooltip title='Cancel automatic annotation' mouseLeaveDelay={0}>
<Icon
type='close'
onClick={() => {
Modal.confirm({
title: 'You are going to cancel automatic annotation?',
content: 'Reached progress will be lost. Continue?',
okType: 'danger',
onOk() {
cancelAutoAnnotation();
},
});
}}
/>
</Tooltip>
</Col>
</Row>
</>
)}
</Col> </Col>
); );
} }

@ -7,10 +7,8 @@ import { connect } from 'react-redux';
import DetailsComponent from 'components/task-page/details'; import DetailsComponent from 'components/task-page/details';
import { updateTaskAsync } from 'actions/tasks-actions'; import { updateTaskAsync } from 'actions/tasks-actions';
import { import { cancelInferenceAsync } from 'actions/models-actions';
Task, import { Task, CombinedState, ActiveInference } from 'reducers/interfaces';
CombinedState,
} from 'reducers/interfaces';
interface OwnProps { interface OwnProps {
task: Task; task: Task;
@ -18,26 +16,32 @@ interface OwnProps {
interface StateToProps { interface StateToProps {
registeredUsers: any[]; registeredUsers: any[];
activeInference: ActiveInference | null;
installedGit: boolean; installedGit: boolean;
} }
interface DispatchToProps { interface DispatchToProps {
cancelAutoAnnotation(): void;
onTaskUpdate: (taskInstance: any) => void; onTaskUpdate: (taskInstance: any) => void;
} }
function mapStateToProps(state: CombinedState): StateToProps { function mapStateToProps(state: CombinedState, own: OwnProps): StateToProps {
const { list } = state.plugins; const { list } = state.plugins;
return { return {
registeredUsers: state.users.users, registeredUsers: state.users.users,
installedGit: list.GIT_INTEGRATION, installedGit: list.GIT_INTEGRATION,
activeInference: state.models.inferences[own.task.instance.id] || null,
}; };
} }
function mapDispatchToProps(dispatch: any): DispatchToProps { function mapDispatchToProps(dispatch: any, own: OwnProps): DispatchToProps {
return { return {
onTaskUpdate: (taskInstance: any): void => dispatch(updateTaskAsync(taskInstance)), onTaskUpdate: (taskInstance: any): void => dispatch(updateTaskAsync(taskInstance)),
cancelAutoAnnotation(): void {
dispatch(cancelInferenceAsync(own.task.instance.id));
},
}; };
} }
@ -46,7 +50,9 @@ function TaskPageContainer(props: StateToProps & DispatchToProps & OwnProps): JS
const { const {
task, task,
installedGit, installedGit,
activeInference,
registeredUsers, registeredUsers,
cancelAutoAnnotation,
onTaskUpdate, onTaskUpdate,
} = props; } = props;
@ -55,8 +61,10 @@ function TaskPageContainer(props: StateToProps & DispatchToProps & OwnProps): JS
previewImage={task.preview} previewImage={task.preview}
taskInstance={task.instance} taskInstance={task.instance}
installedGit={installedGit} installedGit={installedGit}
onTaskUpdate={onTaskUpdate}
registeredUsers={registeredUsers} registeredUsers={registeredUsers}
activeInference={activeInference}
onTaskUpdate={onTaskUpdate}
cancelAutoAnnotation={cancelAutoAnnotation}
/> />
); );
} }

Loading…
Cancel
Save