修复大片底色:加大形态学闭运算等效核尺寸

单次小核(图像/25)闭运算不够大,文字密集区域背景估计被文字
拉低产生灰色底色。改为41x41核多次迭代(3-N次),等效核尺寸
远大于文字行间距,确保背景估计不被文字污染。
后续高斯模糊也加大消除块状伪影。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-19 17:17:28 +08:00
parent 436c02d2a7
commit 487a4d5c05

View File

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