From 5dc20cef566967425bfa7b2b17a6b425d0b0991d Mon Sep 17 00:00:00 2001 From: Codex Date: Sun, 31 May 2026 01:58:57 +0800 Subject: [PATCH] Use fixed bright bone reward --- DICOM_and_UPP配准/static/app.js | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/DICOM_and_UPP配准/static/app.js b/DICOM_and_UPP配准/static/app.js index b02c23f..7670f2d 100644 --- a/DICOM_and_UPP配准/static/app.js +++ b/DICOM_and_UPP配准/static/app.js @@ -67,8 +67,8 @@ const AUTO_PROGRESS_STEPS = [ ]; const BONE_BRIGHT_THRESHOLD = 185; const BONE_EDGE_THRESHOLD = 165; -const BONE_ACTIVATION_GAMMA = 1.65; -const BONE_MAX_REWARD = 1.45; +const BONE_FIXED_REWARD = 1; +const BONE_EDGE_REWARD = 0.22; const STL_DISPLAY_MODES = ["hidden", "solid", "translucent"]; const STL_DISPLAY_LABELS = { hidden: "取消显示", @@ -3045,18 +3045,6 @@ async function prepareAutoFineImageContext(settings) { }; } -function smoothStep(edge0, edge1, value) { - const t = clamp((value - edge0) / Math.max(edge1 - edge0, 0.001), 0, 1); - return t * t * (3 - 2 * t); -} - -function boneBrightnessReward(lum) { - if (lum < BONE_EDGE_THRESHOLD) return 0; - const activation = Math.pow(smoothStep(BONE_EDGE_THRESHOLD, 255, lum), BONE_ACTIVATION_GAMMA); - const brightBoost = smoothStep(BONE_BRIGHT_THRESHOLD, 255, lum); - return activation * (0.35 + BONE_MAX_REWARD * brightBoost); -} - function scorePoseAgainstBoneImages(pose, context, settings) { if (!context?.frames?.length || !context.samples?.length || !context.volumeScene) return NaN; const current = { ...state.pose }; @@ -3103,8 +3091,8 @@ function scorePoseAgainstBoneImages(pose, context, settings) { continue; } const lum = image.data[(y * image.width + x) * 4] || 0; - const reward = boneBrightnessReward(lum); - if (reward > 0) hitReward += reward; + if (lum >= BONE_BRIGHT_THRESHOLD) hitReward += BONE_FIXED_REWARD; + else if (lum >= BONE_EDGE_THRESHOLD) hitReward += BONE_EDGE_REWARD; else missPenalty += 1.05 - (lum / Math.max(BONE_EDGE_THRESHOLD, 1)) * 0.28; contributors += 1; } @@ -3346,7 +3334,7 @@ async function runAutoFine(options = {}) { } setAutoProgress(true, 94, "应用最佳位姿", "正在把本轮最高分候选写回位姿控件和融合视图。", "apply"); state.pose = { ...best.pose }; - state.autoResult = { ...best, evaluated, settings: { ...autoSettingsForStorage(settings), scoring: settings.imageContext ? "activated-bright-bone-window-stl-samples" : "reference-stl-box-overlap", window: "bone", boneThreshold: BONE_BRIGHT_THRESHOLD, boneActivationGamma: BONE_ACTIVATION_GAMMA } }; + state.autoResult = { ...best, evaluated, settings: { ...autoSettingsForStorage(settings), scoring: settings.imageContext ? "fixed-bright-bone-window-stl-samples" : "reference-stl-box-overlap", window: "bone", boneThreshold: BONE_BRIGHT_THRESHOLD, boneReward: BONE_FIXED_REWARD } }; state.lastAutoPose = { before, after: { ...state.pose } }; state.autoDeltaBaseline = { ...before }; renderPoseControls(); @@ -3357,7 +3345,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 ? `骨窗高亮激活评分,亮度越高骨骼奖励越大,${BONE_EDGE_THRESHOLD} 以下扣分` : "参考 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");