Skip to content

Commit

Permalink
fix: classification save&model
Browse files Browse the repository at this point in the history
  • Loading branch information
guhaomine committed Feb 26, 2024
1 parent 87615b6 commit 6a7748c
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 29 deletions.
4 changes: 4 additions & 0 deletions frontend/image-tool/src/businessNew/api/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export async function getModelResult(dataIds: string[], recordId: string) {
args.push(`serialNo=${recordId}`);
return await get(`${url}?${args.join('&')}`);
}
export async function clearModel(dataIds: number[], recordId: string) {
let url = `/api/data/removeModelDataResult`;
let data = await post(url, { serialNo: recordId, dataIds });
}
export async function runModel(config: any) {
const url = `${Api.DATA}/modelAnnotate`;
return await post(url, config);
Expand Down
72 changes: 71 additions & 1 deletion frontend/image-tool/src/businessNew/common/Editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
IModel,
DataTypeEnum,
LoadStatus,
ModelCodeEnum,
} from 'image-editor';
import { getDefault } from '../state';
import { IBSState, ISaveResp } from '../types';
Expand Down Expand Up @@ -58,7 +59,7 @@ export default class Editor extends BaseEditor {
if (saveFrames.length == 0) return;

const { saveDatas } = utils.getDataFlowSaveData(this, saveFrames);
console.log('========> saveDataFlow saveDatas: ', saveDatas);
// console.log('========> saveDataFlow saveDatas: ', saveDatas);
if (saveDatas.length === 0) return;

bsState.doing.saving = true;
Expand Down Expand Up @@ -116,6 +117,75 @@ export default class Editor extends BaseEditor {
return !!(validSource && validClass);
};
}
handleModel() {
const frame = this.getCurrentFrame();
const model = frame.model;
if (!model || !model.code || model.state !== LoadStatus.COMPLETE) return;
const result = this.dataManager.hasModelResult(model.code, frame);
if (result) {
// api.clearModel([+frame.id], model.recordId);
this.addModelData(model.code);
} else {
this.runModel();
}
}
async addModelData(modelCode: ModelCodeEnum) {
const frame = this.getCurrentFrame();
if (!frame || !frame.model) return;
const { state } = this;
const data = this.dataManager.getModelResult(modelCode, frame);
if (!data) return;
const subTitle = this.lang('Add Results?');

const ok = await this.showConfirm({
title: this.lang('Warning'),
subTitle,
okText: this.lang('confirm'),
cancelText: this.lang('cancel'),
okDanger: true,
})
.then(
() => true,
() => false,
)
.catch(() => false);
if (!ok) return;
await this.addInstanceResult(data);
frame.model = undefined;
frame.needSave = true;
this.dataManager.removeModelResult(frame.id);
this.emit(Event.MODEL_RESULT_ADD);
}
async addInstanceResult(data: any) {
const { objects, segmentFileUrl } = data;
if (!objects) {
const errTips = segmentFileUrl
? '检测到有分割模型结果,若想要添加分割模型结果, 请先切换到分割模式'
: '无模型结果数据';
this.handleErr(errTips);
return;
}
const annotates = utils.convertObject2Annotate(
this,
objects.map((o: any) => {
return {
classAttributes: Object.assign({ contour: o }, o.classAttributes || o || {}),
...o,
};
}),
);
annotates.forEach((e) => {
this.initIDInfo(e);
});
if (annotates.length > 0) {
this.cmdManager.withGroup(() => {
if (this.state.isSeriesFrame) {
this.cmdManager.execute('add-track', this.createTrackObj(annotates));
}
this.cmdManager.execute('add-object', annotates);
});
}
}
async runModel() {
const modelConfig = this.state.modelConfig;
if (!modelConfig.model) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
});
function onAttChange(name: string, value: any) {
console.log(name, value);
let dataInfo = editor.getCurrentFrame();
dataInfo.needSave = true;
}
Expand Down
50 changes: 50 additions & 0 deletions frontend/image-tool/src/businessNew/utils/class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,53 @@ export function classificationAssign(baseArr: IClassification[], values: any[])
});
return returnArr;
}

export function classificationToSave(classification: IClassification) {
let attrMap = {} as Record<string, IClassificationAttr>;
classification.attrs.forEach((attr) => {
attrMap[attr.id] = attr;
});
let attrs = classification.attrs.filter((e) => isAttrVisible(e, attrMap) && isAttrHasValue(e));

// find leaf
attrs.forEach((e) => (e.leafFlag = true));
attrs.forEach((e) => {
let parent = e.parent && attrMap[e.parent] ? attrMap[e.parent] : null;
if (parent) parent.leafFlag = false;
});
let data = attrs.map((e) => {
const isParentMulti = e.parent && attrMap[e.parent]?.type === AttrType.MULTI_SELECTION;
return {
id: e.id,
pid: e.parent ? e.parent : null,
name: e.name,
value: e.value,
alias: e.label,
pvalue: isParentMulti ? e.parentValue : undefined,
type: e.type,
isLeaf: !!e.leafFlag,
};
});

return data;
}
export function isAttrVisible(
attr: IClassificationAttr,
attrMap: Record<string, IClassificationAttr>,
): boolean {
if (!attr.parent) return true;
let parentAttr = attrMap[attr.parent];
let visible =
parentAttr.type !== AttrType.MULTI_SELECTION
? parentAttr.value === attr.parentValue
: (parentAttr.value as any[]).indexOf(attr.parentValue) >= 0;

return visible && isAttrVisible(parentAttr, attrMap);
}
export function isAttrHasValue(attr: IClassificationAttr) {
if (attr.type === AttrType.MULTI_SELECTION) {
return Array.isArray(attr.value) && attr.value.length > 0;
} else {
return !!attr.value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { checkPoints } from './common';

export function convertObject2Annotate(editor: Editor, objects: IObjectInfo[]) {
const annotates = [] as AnnotateObject[];

console.log(objects);
objects.forEach((e: IObjectInfo) => {
const obj = e.classAttributes;
const contour = (obj.contour || {}) as IContour;
Expand Down
17 changes: 14 additions & 3 deletions frontend/image-tool/src/businessNew/utils/result-save.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
*
*/
import Editor from '../common/Editor';
import { IContour, IObject, IObjectBasicInfo, ISaveFormat } from '../types';
import { IClassificationAttr, IContour, IObject, IObjectBasicInfo, ISaveFormat } from '../types';
import {
AnnotateObject,
IFrame,
Expand All @@ -16,6 +16,7 @@ import {
SourceType,
} from 'image-editor';
import { checkPoints, empty, fixed, validNumber } from './common';
import { classificationToSave } from './class';

function objToArray(obj: Record<string, any> = {}, attrMap: Map<string, any>) {
const data = [] as any[];
Expand Down Expand Up @@ -134,9 +135,19 @@ export function getDataFlowSaveData(editor: Editor, frames?: IFrame[]) {
});
});
});

const dataAnnotations: any[] = [];
frame.classifications.forEach((classification) => {
let values = classificationToSave(classification);
dataAnnotations.push({
classificationId: classification.id,
classificationAttributes: {
id: classification.id,
values: values,
},
});
});
dataMap[id] = {
dataAnnotations: [],
dataAnnotations: dataAnnotations,
dataId: id,
objects: objectInfos,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const toolMap: Record<ToolName, IToolItemConfig> = {
[ToolName.polygon]: polygonTool,
[ToolName.polyline]: lineTool,
[ToolName['key-point']]: keyPointTool,
// [ToolName.model]: modelTool,
[ToolName.model]: modelTool,
};

// fixed tools
Expand All @@ -30,7 +30,7 @@ const tools_graph: IToolItemConfig[] = [
// segment
const tools_segment: IToolItemConfig[] = [];
// model
const tools_model: IToolItemConfig[] = [];
const tools_model: IToolItemConfig[] = [toolMap[ToolName.model]];
// segment model
const tools_model_seg: IToolItemConfig[] = [];
// instance tools
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import { Editor, IToolItemConfig } from '../..';
import { ToolName } from '../../types/enum';
import { Editor, IToolItemConfig, UIType } from '../..';
import { LoadStatus, ToolName } from '../../types/enum';
import ModelConfig from 'image-ui/components/Tools/components/ModelConfig.vue';

const hasMsg = (editor: Editor) => {
return false;
// const list = editor
// .getModelsByType(ModelTypeEnum.DETECTION)
// .filter((e) => e.code !== ModelCodeEnum.IMAGE_SAM_EMBEDDING);
// const result = list.find((e) => editor.modelManager.hasModelResult(e.code));
// if (result) return true;
// return false;
};
/**
Expand All @@ -19,12 +13,16 @@ export const modelTool: IToolItemConfig = {
name: 'Smart Tool',
hotkey: 'E',
title: 'modelTips',
hasMsg,
hasMsg: (editor: Editor) => {
const frame = editor.getCurrentFrame();
return frame?.model?.state === LoadStatus.COMPLETE;
},
extra: () => ModelConfig,
extraClass: true,
getIcon: (editor?: Editor) => {
getIcon: (editor: Editor) => {
const icon = ToolName.model;
return icon;
const frame = editor.getCurrentFrame();
return frame?.model?.state === LoadStatus.LOADING ? 'loading' : icon;
// if (!editor) return icon;
// const frame = editor.getCurrentFrame();
// if (!frame || !frame.model) return icon;
Expand All @@ -33,13 +31,14 @@ export const modelTool: IToolItemConfig = {
// return isLoading && codes.includes(frame.model.code) ? 'loading' : icon;
},
isDisplay: function (editor: Editor) {
return true;
return editor.state.modeConfig.ui[UIType.model];
// return (
// editor.state.modeConfig.ui[UIType.model] &&
// editor.getModelsByType(ModelTypeEnum.DETECTION, AnnotateModeEnum.INSTANCE).length > 0
// );
},
isActive: function () {
return false;
isActive: function (editor: Editor) {
const frame = editor.getCurrentFrame();
return frame?.model?.state === LoadStatus.LOADING;
},
};
2 changes: 2 additions & 0 deletions frontend/image-tool/src/package/image-editor/types/common.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { IClassification } from '@/businessNew/types';
import {
AnnotateModeEnum,
LoadStatus,
Expand Down Expand Up @@ -57,6 +58,7 @@ export interface IFrame {
model?: IModelRunningState;
// save
needSave?: boolean;
classifications: IClassification[];
// other any
[k: string]: any;
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/image-tool/src/package/image-editor/types/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export enum ToolName {
polyline = 'polyline', // polyline tool, ToolType.POLYLINE
'key-point' = 'key-point', // key-point tool, ToolType.KEY_POINT
// model
// model = 'model',
model = 'model',
}
export enum AnnotateModeEnum {
INSTANCE = 'INSTANCE',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { ref, watchEffect } from 'vue';
import { useInjectEditor } from '../../context';
import { Event, ToolName, toolMap, IToolItemConfig, tools } from '../../../image-editor';
import {
Event,
ToolName,
toolMap,
IToolItemConfig,
tools,
LoadStatus,
} from '../../../image-editor';
interface IToolConfig {
toolItems: IToolItemConfig[];
fixedItems: IToolItemConfig[];
Expand Down Expand Up @@ -100,12 +107,10 @@ export default function useTool() {
break;
}
case 'model': {
// if (editor.mainView.currentDrawTool?.doing()) {
// return editor.showMsg('warning', editor.lang('resultNotComplete'));
// }
const frame = editor.getCurrentFrame();
// const code = editor.state.modelConfig.code;
// if (!code) return;
// editor.handleModel(code);
if (frame?.model?.state !== LoadStatus.COMPLETE) return;
editor.handleModel();
break;
}
}
Expand Down
1 change: 1 addition & 0 deletions frontend/image-tool/src/style/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,6 @@ body {
}

.loading {
display: inline-block;
animation: loading-360 0.8s infinite linear;
}

0 comments on commit 6a7748c

Please sign in to comment.