detection 畫框、classification 改在影像右上角疊標籤(不畫框), 並在推論面板提供即時切換解析方式與上傳 label 檔。 - 新增 InferenceOverlay 依 taskType 分派;ClassificationOverlay 用 DOM 而非 canvas,讓 CJK 排版與 aria-live 交給瀏覽器處理 - 標籤防閃爍:挑戰者需連續 3 幀居冠才切換,或信心度領先 15% 直接切; 低於門檻立即清空(顯示過期標籤比空白更糟) - 身分比對優先用 classIndex,避免換 label 檔時被誤判為換類別 - 推論設定卡片:即時切 detection/classification、上傳 .txt label、 清除 label,皆不需重燒 - classification-result 原本無條件渲染,導致 detection 模式下側欄 永遠顯示「分類結果」與空圖表,改為依 taskType 切換 - 清掉 camera-overlay 每幀執行的 debug console.log - 補 ResizeObserver stub,原本任何渲染 InferencePanel 的測試都會 在 jsdom 直接拋錯 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
54 lines
1.5 KiB
TypeScript
54 lines
1.5 KiB
TypeScript
'use client';
|
|
|
|
import type { InferenceResult } from '@/types/inference';
|
|
import { isClassificationTask } from '@/lib/classification';
|
|
import { CameraOverlay } from './camera-overlay';
|
|
import { ClassificationOverlay } from './classification-overlay';
|
|
|
|
interface InferenceOverlayProps {
|
|
result: InferenceResult | null | undefined;
|
|
width: number;
|
|
height: number;
|
|
confidenceThreshold: number;
|
|
}
|
|
|
|
/**
|
|
* Dispatches the frame overlay based on the task type reported by the
|
|
* inference result itself.
|
|
*
|
|
* `result.taskType` is preferred over the model metadata because it reflects
|
|
* what the Python post-processor actually did — metadata can disagree with the
|
|
* executed code path.
|
|
*
|
|
* Note the branch is written as "is this classification?" rather than "is this
|
|
* detection?" on purpose: the detection task type string has been inconsistent
|
|
* across the stack (`detection` vs `object_detection`, plan R-4), so detection
|
|
* is the fall-through default and stays correct under either spelling.
|
|
*/
|
|
export function InferenceOverlay({
|
|
result,
|
|
width,
|
|
height,
|
|
confidenceThreshold,
|
|
}: InferenceOverlayProps) {
|
|
if (isClassificationTask(result?.taskType)) {
|
|
return (
|
|
<ClassificationOverlay
|
|
classifications={result?.classifications || []}
|
|
width={width}
|
|
height={height}
|
|
confidenceThreshold={confidenceThreshold}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<CameraOverlay
|
|
detections={result?.detections || []}
|
|
width={width}
|
|
height={height}
|
|
confidenceThreshold={confidenceThreshold}
|
|
/>
|
|
);
|
|
}
|