diff --git a/CamScanner.cs b/CamScanner.cs index 5fb7085..de0ca89 100644 --- a/CamScanner.cs +++ b/CamScanner.cs @@ -332,22 +332,24 @@ public static class DocumentScanner Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY); // --- b: 背景估计(形态学闭运算)--- - // 闭运算 = 先膨胀后腐蚀,效果是填平暗区域(文字),保留亮区域(背景) - // 比高斯模糊更好:不会把远处的亮区域扩散到阴影处 - int morphSize = Math.Max(gray.Width, gray.Height) / 25; - if (morphSize < 25) morphSize = 25; - if (morphSize % 2 == 0) morphSize++; + // 闭运算 = 先膨胀后腐蚀,填平暗区域(文字),保留亮区域(背景) + // 核要足够大,能完全覆盖文字笔画和行间距,否则文字密集区域背景被拉低 + // 用多次迭代小核代替单次超大核(性能更好) + int morphSize = 41; + int iterations = Math.Max(gray.Width, gray.Height) / 200; + if (iterations < 3) iterations = 3; Mat morphKernel = Cv2.GetStructuringElement(MorphShapes.Ellipse, new OpenCvSharp.Size(morphSize, morphSize)); Mat background = new Mat(); - Cv2.MorphologyEx(gray, background, MorphTypes.Close, morphKernel); + Cv2.MorphologyEx(gray, background, MorphTypes.Close, morphKernel, + null, iterations); morphKernel.Dispose(); - // 对背景估计做轻度模糊,消除形态学的块状伪影 - int smoothSize = morphSize / 2; + // 对背景估计做模糊,消除形态学的块状伪影 + int smoothSize = morphSize * iterations / 2; if (smoothSize % 2 == 0) smoothSize++; - if (smoothSize < 3) smoothSize = 3; + if (smoothSize < 21) smoothSize = 21; Cv2.GaussianBlur(background, background, new OpenCvSharp.Size(smoothSize, smoothSize), 0); // --- c: 减法提取墨迹 ---