diff --git a/CamScanner.cs b/CamScanner.cs index 47202b9..551dccf 100644 --- a/CamScanner.cs +++ b/CamScanner.cs @@ -367,18 +367,14 @@ public static class DocumentScanner Marshal.Copy(resultData, 0, normU8.Data, resultData.Length); // --- d: 非线性对比度增强 --- - // gamma 曲线压暗 + 线性拉伸加深,两步结合: - // gamma 保留笔画间灰度层次 - // 线性拉伸让文字整体更黑 + // gamma 曲线压暗,保留笔画间灰度层次 + // 输出范围压到 0-150,给白底清理留空间 byte[] lut = new byte[256]; for (int i = 0; i < 256; i++) { double x = i / 255.0; - // gamma=2.2 压暗 - double y = Math.Pow(x, 2.2); - // 再做线性拉伸:输出范围压缩到 0-200,之后白底清理会把200+推白 - // 这样文字更黑但笔画间差异按比例保留 - int val = (int)(y * 200.0); + double y = Math.Pow(x, 2.5); + int val = (int)(y * 150.0); if (val > 255) val = 255; lut[i] = (byte)val; } @@ -397,17 +393,37 @@ public static class DocumentScanner contrasted.Dispose(); // --- f: 白底清理 --- - // gamma后文字大约在 0-80,背景大约在 150-200 - // 阈值 160:>160 的推白(背景),<160 的保留(文字) - Cv2.Threshold(sharpened, sharpened, 160, 255, ThresholdTypes.Trunc); - Cv2.ConvertScaleAbs(sharpened, sharpened, 255.0 / 160.0, 0); + // 用 LUT:<60 保持原值(文字),60-150 快速过渡到白色,>150 纯白 + byte[] whiteLut = new byte[256]; + for (int i = 0; i < 256; i++) + { + if (i <= 60) + { + whiteLut[i] = (byte)i; // 文字保持不变 + } + else if (i <= 150) + { + // 平滑过渡到白色 + double t = (double)(i - 60) / 90.0; + whiteLut[i] = (byte)(60 + (int)(t * t * 195)); // 60→255 + } + else + { + whiteLut[i] = 255; // 纯白 + } + } + Mat whiteLutMat = new Mat(1, 256, MatType.CV_8U, whiteLut); + Mat cleaned = new Mat(); + Cv2.LUT(sharpened, whiteLutMat, cleaned); + whiteLutMat.Dispose(); + sharpened.Dispose(); // 转回3通道 Mat output = new Mat(); - Cv2.CvtColor(sharpened, output, ColorConversionCodes.GRAY2BGR); + Cv2.CvtColor(cleaned, output, ColorConversionCodes.GRAY2BGR); gray.Dispose(); - sharpened.Dispose(); + cleaned.Dispose(); src.Dispose(); return output;