From 3db5e9f6f7059994eb511ab6c99b6220a50dd355 Mon Sep 17 00:00:00 2001 From: sinvo Date: Fri, 20 Mar 2026 08:46:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E8=BE=B9=E7=BC=98=E9=98=B4?= =?UTF-8?q?=E5=BD=B1=E6=89=AB=E6=8F=8F=EF=BC=9A=E5=AE=B9=E5=BF=8D=E8=B7=B3?= =?UTF-8?q?=E8=BF=875=E4=B8=AA=E4=BA=AE=E5=83=8F=E7=B4=A0=E3=80=81?= =?UTF-8?q?=E9=98=88=E5=80=BC65%=E3=80=81=E6=B7=B1=E5=BA=A61/3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 之前遇到一个亮像素就停止,阴影中夹杂的稍亮像素会打断扫描。 改为允许跳过最多5个亮像素继续扫描,记录最后一个暗像素位置, 把从边缘到该位置的所有像素都设为白色。 阈值从60%提到65%,扫描深度从1/4加到1/3。 Co-Authored-By: Claude Opus 4.6 --- CamScanner.cs | 61 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/CamScanner.cs b/CamScanner.cs index f8ad70e..d99ab6a 100644 --- a/CamScanner.cs +++ b/CamScanner.cs @@ -437,8 +437,9 @@ public static class DocumentScanner } } int paperBright = (int)(centerSum / Math.Max(centerCount, 1)); - int darkThresh = (int)(paperBright * 0.6); - int maxScanDepth = Math.Max(w, h) / 4; // 最多扫描1/4深度 + int darkThresh = (int)(paperBright * 0.65); + int maxScanDepth = Math.Max(w, h) / 3; // 最多扫描1/3深度 + int tolerance = 5; // 允许跳过最多5个亮像素继续扫描 byte[] cleanedData = new byte[w * h]; Marshal.Copy(cleaned.Data, cleanedData, 0, cleanedData.Length); @@ -446,46 +447,86 @@ public static class DocumentScanner // 上边缘 for (int x = 0; x < w; x++) { + int skipCount = 0; + int lastDark = -1; for (int y = 0; y < Math.Min(maxScanDepth, h); y++) { if (grayData[y * w + x] < darkThresh) - cleanedData[y * w + x] = 255; + { + lastDark = y; + skipCount = 0; + } else - break; + { + skipCount++; + if (skipCount > tolerance) break; + } } + for (int y = 0; y <= lastDark; y++) + cleanedData[y * w + x] = 255; } // 下边缘 for (int x = 0; x < w; x++) { + int skipCount = 0; + int lastDark = h; for (int y = h - 1; y >= Math.Max(0, h - maxScanDepth); y--) { if (grayData[y * w + x] < darkThresh) - cleanedData[y * w + x] = 255; + { + lastDark = y; + skipCount = 0; + } else - break; + { + skipCount++; + if (skipCount > tolerance) break; + } } + for (int y = h - 1; y >= lastDark; y--) + cleanedData[y * w + x] = 255; } // 左边缘 for (int py = 0; py < h; py++) { + int skipCount = 0; + int lastDark = -1; for (int x = 0; x < Math.Min(maxScanDepth, w); x++) { if (grayData[py * w + x] < darkThresh) - cleanedData[py * w + x] = 255; + { + lastDark = x; + skipCount = 0; + } else - break; + { + skipCount++; + if (skipCount > tolerance) break; + } } + for (int x = 0; x <= lastDark; x++) + cleanedData[py * w + x] = 255; } // 右边缘 for (int py = 0; py < h; py++) { + int skipCount = 0; + int lastDark = w; for (int x = w - 1; x >= Math.Max(0, w - maxScanDepth); x--) { if (grayData[py * w + x] < darkThresh) - cleanedData[py * w + x] = 255; + { + lastDark = x; + skipCount = 0; + } else - break; + { + skipCount++; + if (skipCount > tolerance) break; + } } + for (int x = w - 1; x >= lastDark; x--) + cleanedData[py * w + x] = 255; } Marshal.Copy(cleanedData, 0, cleaned.Data, cleanedData.Length);