diff --git a/server/workspace/datasets/兔子/32058343-7231-41c9-884f-44175e1cf090.jpg b/server/workspace/datasets/兔子/32058343-7231-41c9-884f-44175e1cf090.jpg new file mode 100644 index 0000000..5f9440e Binary files /dev/null and b/server/workspace/datasets/兔子/32058343-7231-41c9-884f-44175e1cf090.jpg differ diff --git a/server/workspace/datasets/雉鸡/0d013220-1a1a-4a44-84b0-e5616b7604a5.jpg b/server/workspace/datasets/雉鸡/0d013220-1a1a-4a44-84b0-e5616b7604a5.jpg new file mode 100644 index 0000000..93e13b3 Binary files /dev/null and b/server/workspace/datasets/雉鸡/0d013220-1a1a-4a44-84b0-e5616b7604a5.jpg differ diff --git a/server/workspace/datasets/鸭子/0361b693-fe4b-4098-8dd9-c2973e77289e.jpg b/server/workspace/datasets/鸭子/0361b693-fe4b-4098-8dd9-c2973e77289e.jpg new file mode 100644 index 0000000..c1cb33c Binary files /dev/null and b/server/workspace/datasets/鸭子/0361b693-fe4b-4098-8dd9-c2973e77289e.jpg differ diff --git a/server/workspace/datasets/鸽子/f2a8cf0e-534e-4aba-9288-54d8d2180666.jpg b/server/workspace/datasets/鸽子/f2a8cf0e-534e-4aba-9288-54d8d2180666.jpg new file mode 100644 index 0000000..9712d75 Binary files /dev/null and b/server/workspace/datasets/鸽子/f2a8cf0e-534e-4aba-9288-54d8d2180666.jpg differ diff --git a/server/workspace/datasets/鹌鹑/d5dc7788-dd70-44ae-901b-5c2f9de242b1.jpg b/server/workspace/datasets/鹌鹑/d5dc7788-dd70-44ae-901b-5c2f9de242b1.jpg new file mode 100644 index 0000000..3c0da36 Binary files /dev/null and b/server/workspace/datasets/鹌鹑/d5dc7788-dd70-44ae-901b-5c2f9de242b1.jpg differ diff --git a/server_admin/src/views/DatasetDetail.vue b/server_admin/src/views/DatasetDetail.vue index dd4fa8e..48c677b 100644 --- a/server_admin/src/views/DatasetDetail.vue +++ b/server_admin/src/views/DatasetDetail.vue @@ -137,7 +137,7 @@ function stopLabelPoll() { // 全量标注:重扫数据集全部图片,覆盖各图已有标注(含人工修改/清理的框) function startFullLabelTask() { - ElMessageBox.confirm('将重新扫描数据集全部图片并生成标注,覆盖各图已有标注(含人工修改/清理的框)。确定继续?', '全量标注', { + ElMessageBox.confirm('将重新扫描数据集全部图片并生成标注,覆盖各图已有标注(含人工确认/清理的结果)。确定继续?', '全量标注', { confirmButtonText: '开始标注', cancelButtonText: '取消', type: 'warning', @@ -200,9 +200,7 @@ const naturalW = ref(0) const naturalH = ref(0) const confirmed = ref([]) const dirty = ref(false) -const drawing = ref(null) const pointerDownPos = ref(null) -const newClass = ref(0) const saving = ref(false) // class 0 = 确认(红框),class 1 = 疑似(黄框) const classColor = ['#f56c6c', '#e6a23c'] @@ -243,6 +241,15 @@ function removeBox(i) { draw() } +// 疑似框确认(class1 → class0):VLM 补检产出的疑似框由人工确认 +function confirmBox(i) { + const b = confirmed.value[i] + if (!b || b.class !== 1) return + b.class = 0 + markDirty() + draw() +} + function openEditor(item, gi) { editIndex.value = gi editorVisible.value = true @@ -285,7 +292,6 @@ function resetEditor() { stopHighlight() dirty.value = false confirmed.value = [] - drawing.value = null if (currentImage.value) { confirmed.value = (currentImage.value.boxes || []).map((b) => ({ ...b })) } @@ -364,17 +370,6 @@ function draw() { const b = confirmed.value[i] drawBox(ctx, b, false, i === highlightIndex.value && highlightOn.value) } - - if (drawing.value) { - const b = { - cx: drawing.value.x + drawing.value.w / 2, - cy: drawing.value.y + drawing.value.h / 2, - w: drawing.value.w, - h: drawing.value.h, - class: newClass.value, - } - drawBox(ctx, b, true) - } } function drawBox(ctx, box, ghost = false, highlighted = false) { @@ -419,48 +414,20 @@ function onPointerDown(e) { e.preventDefault() const pos = eventPos(e) pointerDownPos.value = { ...pos } - drawing.value = null canvasEl.value.setPointerCapture(e.pointerId) } -function onPointerMove(e) { - if (!pointerDownPos.value) return - e.preventDefault() - const pos = eventPos(e) - drawing.value = { - x: Math.min(pointerDownPos.value.x, pos.x), - y: Math.min(pointerDownPos.value.y, pos.y), - w: Math.abs(pos.x - pointerDownPos.value.x), - h: Math.abs(pos.y - pointerDownPos.value.y), - } - draw() -} - +// 点击框选中(审核模式:不做手动画框,疑似框由 VLM 补检产出,人工仅确认/删除) function onPointerUp(e) { if (!pointerDownPos.value) return const pos = eventPos(e) const moved = Math.abs(pos.x - pointerDownPos.value.x) + Math.abs(pos.y - pointerDownPos.value.y) pointerDownPos.value = null - - if (drawing.value && drawing.value.w * drawing.value.h > 0.0002) { - confirmed.value.push({ - cx: drawing.value.x + drawing.value.w / 2, - cy: drawing.value.y + drawing.value.h / 2, - w: drawing.value.w, - h: drawing.value.h, - confidence: 1, - class: newClass.value, - }) - markDirty() - } else if (moved < 0.03) { - // 点框删除(人工框与 AI 自动标注同操作,可逐框清理) + if (moved < 0.03) { const idx = confirmed.value.findIndex((b) => pointInBox(pos, b)) - if (idx >= 0) { - confirmed.value.splice(idx, 1) - markDirty() - } + if (idx >= 0) toggleHighlight(idx) + else stopHighlight() } - drawing.value = null draw() } @@ -576,7 +543,7 @@ onBeforeUnmount(() => {