bonus-ui/src/views/dataCenter/annotationTask/child/customLabelStudio.vue

228 lines
6.1 KiB
Vue
Raw Normal View History

2024-11-28 12:27:07 +08:00
<template>
2024-12-01 15:08:48 +08:00
<div class="label-studio-annotator">
<div id="label-studio" class="annotation-container"></div>
2024-11-28 12:27:07 +08:00
</div>
</template>
<script>
2024-12-01 15:08:48 +08:00
import LabelStudio from 'label-studio';
2024-12-03 16:19:33 +08:00
import '@/assets/styles/labelStudio.scss';
2024-12-01 15:08:48 +08:00
import { manualAnnotate } from '../../../../api/dataCenter/annotationTask';
2024-11-28 12:27:07 +08:00
export default {
2024-12-01 15:08:48 +08:00
name: 'LabelStudioAnnotator',
2024-11-28 12:27:07 +08:00
props: {
2024-12-01 15:08:48 +08:00
fileUrl: { type: String, required: true },
taskId: { type: Number, required: true },
config: { type: String, required: true },
id: { type: Number, required: true },
itemIndex: { type: Number, required: true },
2024-12-03 16:35:45 +08:00
fileAnnotationStatus: { type: String, required: true },
2024-12-01 15:08:48 +08:00
annotations: {
type: Array,
default: () => [] // 默认值为空数组
}
},
computed: {
index: {
get() {
return this.itemIndex;
},
set(value) {
2024-12-02 10:46:26 +08:00
this.$parent.updateItemIndex(value,this.label); // 更新父组件的索引
2024-12-01 15:08:48 +08:00
}
2024-11-28 12:27:07 +08:00
}
},
data() {
return {
2024-12-02 10:46:26 +08:00
label:null,
2024-11-28 12:27:07 +08:00
labelStudio: null,
2024-12-01 15:08:48 +08:00
annotationsList: [] // 用于存储当前标注的结果
};
2024-11-28 12:27:07 +08:00
},
2024-12-01 15:08:48 +08:00
watch: {
fileUrl: 'resetLabelStudio' // 当文件地址变化时重置LabelStudio
2024-12-01 09:48:41 +08:00
},
2024-11-28 12:27:07 +08:00
mounted() {
2024-12-01 15:08:48 +08:00
this.initLabelStudio(); // 组件挂载完成后初始化LabelStudio
2024-11-28 12:27:07 +08:00
},
methods: {
2024-12-01 15:08:48 +08:00
// 处理返回的标注数据
getAnnotations() {
return [{
result: this.annotations.map(annotation => ({
type: "rectanglelabels",
from_name: "label",
to_name: "image",
value: {
rectanglelabels: [annotation.label],
x: annotation.x,
y: annotation.y,
width: annotation.width,
height: annotation.height
}
}))
}];
},
// 初始化 LabelStudio
2024-11-28 12:27:07 +08:00
initLabelStudio() {
2024-12-01 15:08:48 +08:00
this.cleanupLabelStudio(); // 清理之前的实例
const task = {
id: this.id,
data: { image: this.fileUrl },
};
2024-12-02 01:44:31 +08:00
if (this.annotations) {
2024-12-01 15:08:48 +08:00
task.annotations = this.getAnnotations();
}
2024-12-03 16:35:45 +08:00
let interfaces = [];
if (this.fileAnnotationStatus === '2'){
interfaces = ["controls"];
}else {
interfaces = ["panel","update", "submit", "controls"];
}
2024-12-01 15:08:48 +08:00
this.$nextTick(() => {
const labelStudioElement = document.getElementById('label-studio');
if (!labelStudioElement) {
console.error('Label Studio element not found');
return;
2024-11-28 12:27:07 +08:00
}
2024-12-01 15:08:48 +08:00
this.labelStudio = new LabelStudio('label-studio', {
config: this.config,
2024-12-03 16:35:45 +08:00
interfaces: interfaces,
2024-12-01 15:08:48 +08:00
user: { pk: 1, firstName: '标注者', lastName: '用户' },
task,
onLabelStudioLoad: (LS) => {
if (!LS.annotationStore.selectedAnnotation) {
const annotation = LS.annotationStore.addAnnotation({ userGenerate: true });
LS.annotationStore.selectAnnotation(annotation.id);
}
2024-12-02 14:58:29 +08:00
this.changeButtonText(LS);
2024-12-01 15:08:48 +08:00
},
onSubmitAnnotation: (LS, annotation) => this.handleAnnotationSubmit(LS, annotation, task),
2025-01-12 16:39:32 +08:00
//onUpdateAnnotation:(LS, annotation) => this.handleAnnotationSubmit(LS, annotation, task),
2024-12-01 15:08:48 +08:00
});
2024-11-28 12:27:07 +08:00
});
},
2024-12-01 15:08:48 +08:00
// 提交标注结果
async handleAnnotationSubmit(LS, annotation, task) {
const results = annotation.serializeAnnotation();
2024-12-02 11:19:17 +08:00
console.log(results)
if (results.length === 0) return;
2024-12-01 15:08:48 +08:00
const formattedAnnotations = results.map(result => {
if (result.type === 'rectanglelabels') {
return {
label: result.value.rectanglelabels[0],
x: result.value.x,
y: result.value.y,
width: result.value.width,
height: result.value.height
};
}
return result;
});
2024-11-28 12:27:07 +08:00
2024-12-01 15:08:48 +08:00
const data = {
annotationResult: JSON.stringify(formattedAnnotations),
taskId: this.taskId,
fileId: this.id
};
try {
await manualAnnotate(data);
this.annotationsList.push({
taskId: task.id,
annotation: JSON.stringify(formattedAnnotations),
url: this.fileUrl
});
2024-12-02 10:46:26 +08:00
this.label = JSON.stringify(formattedAnnotations)
2024-12-01 15:08:48 +08:00
this.index++; // 更新索引
} catch (error) {
console.error('Failed to submit annotation:', error);
} finally {
this.cleanupLabelStudio(); // 清理 LabelStudio 实例
2024-11-28 12:27:07 +08:00
}
},
2024-12-02 14:58:29 +08:00
changeButtonText(LS) {
const buttons = {
'Undo': '撤销',
'Redo': '重做',
'Reset': '重置',
'Submit': '提交',
'Update':'更新'
};
const updateButtonText = (element) => {
const buttonElements = element.querySelectorAll('button');
buttonElements.forEach((button) => {
const text = button.textContent.trim();
if (buttons[text]) {
button.textContent = buttons[text];
}
});
};
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE) {
updateButtonText(node);
}
});
}
});
});
observer.observe(document.body, { childList: true, subtree: true });
updateButtonText(document.body);
},
2024-12-03 15:17:56 +08:00
2024-12-01 15:08:48 +08:00
// 重置 LabelStudio
resetLabelStudio() {
this.cleanupLabelStudio();
this.initLabelStudio(); // 重新初始化
},
// 清理 LabelStudio 实例
cleanupLabelStudio() {
if (this.labelStudio && this.labelStudio.destroy) {
this.labelStudio.destroy();
2024-11-28 12:27:07 +08:00
}
2024-12-01 15:08:48 +08:00
const labelStudioElement = document.getElementById('label-studio');
if (labelStudioElement) {
labelStudioElement.innerHTML = ''; // 清空容器
2024-11-28 12:27:07 +08:00
}
2024-12-01 15:08:48 +08:00
this.labelStudio = null; // 置空实例
2024-11-28 12:27:07 +08:00
}
}
2024-12-01 15:08:48 +08:00
};
2024-11-28 12:27:07 +08:00
</script>
2024-12-03 15:17:56 +08:00
<style lang="scss">
.label-studio-annotator{
2024-12-01 15:08:48 +08:00
width: 100%;
2024-12-03 15:17:56 +08:00
height: 100%;
2024-12-01 15:08:48 +08:00
}
2024-12-03 15:17:56 +08:00
.annotation-container{
2024-11-28 12:27:07 +08:00
width: 100%;
2024-12-01 15:08:48 +08:00
height: 100%;
2024-12-03 15:17:56 +08:00
display: flex;
align-items: center;
justify-content: center;
>div{
width: 100%;
height: 100%;
padding: 5px;
}
2024-11-28 12:27:07 +08:00
}
2024-12-03 15:17:56 +08:00
2024-11-28 12:27:07 +08:00
</style>