// Copyright (C) 2020 Intel Corporation // // SPDX-License-Identifier: MIT import './styles.scss'; import React, { useState } from 'react'; import { Row, Col } from 'antd/lib/grid'; import Icon from 'antd/lib/icon'; import Select, { OptionProps } from 'antd/lib/select'; import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox'; import Tooltip from 'antd/lib/tooltip'; import Tag from 'antd/lib/tag'; import Text from 'antd/lib/typography/Text'; import InputNumber from 'antd/lib/input-number'; import Button from 'antd/lib/button'; import notification from 'antd/lib/notification'; import { Model, StringObject } from 'reducers/interfaces'; import consts from 'consts'; interface Props { withCleanup: boolean; models: Model[]; task: any; runInference(task: any, model: Model, body: object): void; } function DetectorRunner(props: Props): JSX.Element { const { task, models, withCleanup, runInference, } = props; const [modelID, setModelID] = useState(null); const [mapping, setMapping] = useState({}); const [threshold, setThreshold] = useState(0.5); const [distance, setDistance] = useState(50); const [cleanup, setCleanup] = useState(false); const [match, setMatch] = useState<{ model: string | null; task: string | null; }>({ model: null, task: null, }); const model = models.filter((_model): boolean => _model.id === modelID)[0]; const isDetector = model && model.type === 'detector'; const isReId = model && model.type === 'reid'; const buttonEnabled = model && (model.type === 'reid' || ( model.type === 'detector' && !!Object.keys(mapping).length )); const modelLabels = (isDetector ? model.labels : []) .filter((_label: string): boolean => !(_label in mapping)); const taskLabels = (isDetector && !!task ? task.labels.map((label: any): string => label.name) : [] ); if (model && model.type !== 'reid' && !model.labels.length) { notification.warning({ message: 'The selected model does not include any lables', }); } function updateMatch(modelLabel: string | null, taskLabel: string | null): void { if (match.model && taskLabel) { const newmatch: { [index: string]: string } = {}; newmatch[match.model] = taskLabel; setMapping({ ...mapping, ...newmatch }); setMatch({ model: null, task: null }); return; } if (match.task && modelLabel) { const newmatch: { [index: string]: string } = {}; newmatch[modelLabel] = match.task; setMapping({ ...mapping, ...newmatch }); setMatch({ model: null, task: null }); return; } setMatch({ model: modelLabel, task: taskLabel, }); } function renderSelector( value: string, tooltip: string, labels: string[], onChange: (label: string) => void, ): JSX.Element { return ( ); } return (
Model: { isDetector && !!Object.keys(mapping).length && ( Object.keys(mapping).map((modelLabel: string) => { const label = task.labels .filter((_label: any): boolean => _label.name === mapping[modelLabel])[0]; const color = label ? label.color : consts.NEW_LABEL_COLOR; return ( {modelLabel} {mapping[modelLabel]} { const newmapping = { ...mapping }; delete newmapping[modelLabel]; setMapping(newmapping); }} /> ); }) )} { isDetector && !!taskLabels.length && !!modelLabels.length && ( <> {renderSelector( match.model || '', 'Model labels', modelLabels, (modelLabel: string) => updateMatch(modelLabel, null), )} {renderSelector( match.task || '', 'Task labels', taskLabels, (taskLabel: string) => updateMatch(null, taskLabel), )} )} { isDetector && withCleanup && (
setCleanup(e.target.checked)} > Clean old annotations
)} { isReId && (
Threshold { if (typeof (value) === 'number') { setThreshold(value); } }} /> Maximum distance { if (typeof (value) === 'number') { setDistance(value); } }} />
) }
); } export default React.memo(DetectorRunner, (prevProps: Props, nextProps: Props): boolean => ( prevProps.task === nextProps.task && prevProps.runInference === nextProps.runInference && prevProps.models.length === nextProps.models.length && nextProps.models.reduce((acc: boolean, model: Model, index: number): boolean => ( acc && model.id === prevProps.models[index].id ), true) ));