diff --git a/CamScanner.cs b/CamScanner.cs index 2d0b19c..f4aa19a 100644 --- a/CamScanner.cs +++ b/CamScanner.cs @@ -394,10 +394,11 @@ public static class DocumentScanner // 墨迹映射(带阴影/折痕保护) // 文字特征:背景亮(接近paperBright),gray比背景低 → ink大 // 折痕/阴影特征:gray本身就暗,背景估计也被拉低 → ink也可能大 - // 区分方法:看背景估计值是否接近正常纸面亮度 - // 如果 bgData[i] 接近 paperBright → 正常文字区域,正常处理 - // 如果 bgData[i] 远低于 paperBright → 阴影/折痕区域,抑制墨迹深度 - double bgThreshRatio = 0.75; // 背景低于纸面亮度75%就开始抑制 + // 区分方法: + // 1. 看背景估计值是否接近正常纸面亮度(抑制阴影区域的墨迹) + // 2. 看原始灰度值本身是否偏暗(折痕处gray很低) + double bgThreshHigh = 0.92; // 背景低于纸面亮度92%就开始轻微抑制 + double bgThreshLow = 0.60; // 低于60%时完全抑制为白色 for (int i = 0; i < grayData.Length; i++) { @@ -409,14 +410,34 @@ public static class DocumentScanner double darkness = Math.Pow(inkNorm, 0.45); - // 阴影/折痕抑制:背景越暗,墨迹输出越浅 + // 阴影/折痕抑制 double bgRatio = (double)bgData[i] / Math.Max(paperBright, 1); - if (bgRatio < bgThreshRatio) + + if (bgRatio < bgThreshHigh) { - // 背景很暗 → 阴影区域,大幅抑制 - // 线性衰减:bgRatio从0.75→0时,darkness从原值→0 - double suppress = bgRatio / bgThreshRatio; - darkness = darkness * suppress * suppress; // 平方衰减,更激进 + if (bgRatio <= bgThreshLow) + { + // 极暗区域,完全抑制 + darkness = 0; + } + else + { + // 平滑衰减:从bgThreshHigh到bgThreshLow,darkness从原值→0 + double t = (bgRatio - bgThreshLow) / (bgThreshHigh - bgThreshLow); + // 用三次曲线平滑过渡 + t = t * t * (3.0 - 2.0 * t); + darkness = darkness * t; + } + } + + // 额外保护:原始灰度本身很暗且不是文字(ink占gray比例小) + // 折痕:gray很低(比如100),ink可能只有20-30,ink/gray比例小 + // 文字:gray中等(比如150),ink可能50-80,ink/gray比例大 + double grayRatio = (double)grayData[i] / Math.Max(paperBright, 1); + if (grayRatio < 0.5 && ink < bgData[i] * 0.3) + { + // 原始灰度很暗,但墨迹占比小 → 不是文字,是阴影/折痕 + darkness = darkness * 0.1; } int val = (int)(255.0 * (1.0 - darkness));