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

单次小核(图像/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);
// --- 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: 减法提取墨迹 ---