diff --git a/DICOM_and_UPP配准/static/app.js b/DICOM_and_UPP配准/static/app.js index 0fbc169..b7b9655 100644 --- a/DICOM_and_UPP配准/static/app.js +++ b/DICOM_and_UPP配准/static/app.js @@ -65,6 +65,8 @@ const AUTO_PROGRESS_STEPS = [ { id: "score", label: "评分" }, { id: "apply", label: "应用" }, ]; +const BONE_BRIGHT_THRESHOLD = 185; +const BONE_EDGE_THRESHOLD = 165; const STL_DISPLAY_MODES = ["hidden", "solid", "translucent"]; const STL_DISPLAY_LABELS = { hidden: "取消显示", @@ -3087,10 +3089,9 @@ function scorePoseAgainstBoneImages(pose, context, settings) { continue; } const lum = image.data[(y * image.width + x) * 4] || 0; - if (lum >= 170) hitReward += 1; - else if (lum >= 115) hitReward += 0.45; - else if (lum >= 80) hitReward += 0.16; - else missPenalty += 0.9 - lum / 255; + if (lum >= BONE_BRIGHT_THRESHOLD) hitReward += lum >= 215 ? 1.18 : 1; + else if (lum >= BONE_EDGE_THRESHOLD) hitReward += 0.22; + else missPenalty += 1.05 - (lum / Math.max(BONE_EDGE_THRESHOLD, 1)) * 0.28; contributors += 1; } const safeContributors = Math.max(contributors, 1); @@ -3254,7 +3255,7 @@ async function runAutoFine(options = {}) { setAutoProgress(true, 22, "采样参考 STL", "正在从勾选的参考 STL 和骨窗切片中构建评分样本。", "sample"); settings.imageContext = await prepareAutoFineImageContext(settings); const imageContextText = settings.imageContext - ? `已采样 ${settings.imageContext.samples.length} 个 STL 点、${settings.imageContext.frames.length} 张骨窗切片。` + ? `已采样 ${settings.imageContext.samples.length} 个 STL 点、${settings.imageContext.frames.length} 张骨窗切片;仅高亮骨性像素参与正向奖励。` : "未能建立骨窗像素样本,将退回 DICOM/STL 三维盒体评分。"; setAutoProgress(true, 38, "建立候选队列", imageContextText, "score"); await waitForUiFrame(); @@ -3331,7 +3332,7 @@ async function runAutoFine(options = {}) { } setAutoProgress(true, 94, "应用最佳位姿", "正在把本轮最高分候选写回位姿控件和融合视图。", "apply"); state.pose = { ...best.pose }; - state.autoResult = { ...best, evaluated, settings: { ...autoSettingsForStorage(settings), scoring: settings.imageContext ? "bone-window-stl-samples" : "reference-stl-box-overlap", window: "bone" } }; + state.autoResult = { ...best, evaluated, settings: { ...autoSettingsForStorage(settings), scoring: settings.imageContext ? "strict-bright-bone-window-stl-samples" : "reference-stl-box-overlap", window: "bone", boneThreshold: BONE_BRIGHT_THRESHOLD } }; state.lastAutoPose = { before, after: { ...state.pose } }; state.autoDeltaBaseline = { ...before }; renderPoseControls(); @@ -3342,7 +3343,7 @@ async function runAutoFine(options = {}) { const scoreText = Number.isFinite(best.score) ? best.score.toFixed(4) : "不可用"; const referenceText = describeAutoReference(settings); $("autoResult").textContent = changed - ? `本轮最高分候选:${best.mode};score ${scoreText};评估 ${evaluated} 个候选;${settings.imageContext ? "骨窗像素采样 + STL 参考评分" : "参考 STL 盒体评分"};${referenceText}。` + ? `本轮最高分候选:${best.mode};score ${scoreText};评估 ${evaluated} 个候选;${settings.imageContext ? `严格骨窗高亮评分,亮度 ≥ ${BONE_BRIGHT_THRESHOLD} 才作为骨骼命中` : "参考 STL 盒体评分"};${referenceText}。` : `本轮未找到比当前位姿更高分的候选;score ${scoreText};评估 ${evaluated} 个候选。这不代表已配准正确,只说明当前搜索范围和参考 STL 下没有更高分;${referenceText};自动微调目前只调整平移/缩放,明显旋转错位需要先手动校正。`; updateAutoPoseResult(before, state.pose); setAutoProgress(true, 100, changed ? "微调完成" : "本轮未改动", changed ? `已应用 ${best.mode}。` : "没有强行移动模型;请检查参考 STL 和大角度旋转。", "apply");