增强边缘阴影扫描:容忍跳过5个亮像素、阈值65%、深度1/3
之前遇到一个亮像素就停止,阴影中夹杂的稍亮像素会打断扫描。 改为允许跳过最多5个亮像素继续扫描,记录最后一个暗像素位置, 把从边缘到该位置的所有像素都设为白色。 阈值从60%提到65%,扫描深度从1/4加到1/3。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -437,8 +437,9 @@ public static class DocumentScanner
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
int paperBright = (int)(centerSum / Math.Max(centerCount, 1));
|
int paperBright = (int)(centerSum / Math.Max(centerCount, 1));
|
||||||
int darkThresh = (int)(paperBright * 0.6);
|
int darkThresh = (int)(paperBright * 0.65);
|
||||||
int maxScanDepth = Math.Max(w, h) / 4; // 最多扫描1/4深度
|
int maxScanDepth = Math.Max(w, h) / 3; // 最多扫描1/3深度
|
||||||
|
int tolerance = 5; // 允许跳过最多5个亮像素继续扫描
|
||||||
|
|
||||||
byte[] cleanedData = new byte[w * h];
|
byte[] cleanedData = new byte[w * h];
|
||||||
Marshal.Copy(cleaned.Data, cleanedData, 0, cleanedData.Length);
|
Marshal.Copy(cleaned.Data, cleanedData, 0, cleanedData.Length);
|
||||||
@@ -446,46 +447,86 @@ public static class DocumentScanner
|
|||||||
// 上边缘
|
// 上边缘
|
||||||
for (int x = 0; x < w; x++)
|
for (int x = 0; x < w; x++)
|
||||||
{
|
{
|
||||||
|
int skipCount = 0;
|
||||||
|
int lastDark = -1;
|
||||||
for (int y = 0; y < Math.Min(maxScanDepth, h); y++)
|
for (int y = 0; y < Math.Min(maxScanDepth, h); y++)
|
||||||
{
|
{
|
||||||
if (grayData[y * w + x] < darkThresh)
|
if (grayData[y * w + x] < darkThresh)
|
||||||
cleanedData[y * w + x] = 255;
|
{
|
||||||
else
|
lastDark = y;
|
||||||
break;
|
skipCount = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
skipCount++;
|
||||||
|
if (skipCount > tolerance) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int y = 0; y <= lastDark; y++)
|
||||||
|
cleanedData[y * w + x] = 255;
|
||||||
}
|
}
|
||||||
// 下边缘
|
// 下边缘
|
||||||
for (int x = 0; x < w; x++)
|
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--)
|
for (int y = h - 1; y >= Math.Max(0, h - maxScanDepth); y--)
|
||||||
{
|
{
|
||||||
if (grayData[y * w + x] < darkThresh)
|
if (grayData[y * w + x] < darkThresh)
|
||||||
cleanedData[y * w + x] = 255;
|
{
|
||||||
else
|
lastDark = y;
|
||||||
break;
|
skipCount = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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++)
|
for (int py = 0; py < h; py++)
|
||||||
{
|
{
|
||||||
|
int skipCount = 0;
|
||||||
|
int lastDark = -1;
|
||||||
for (int x = 0; x < Math.Min(maxScanDepth, w); x++)
|
for (int x = 0; x < Math.Min(maxScanDepth, w); x++)
|
||||||
{
|
{
|
||||||
if (grayData[py * w + x] < darkThresh)
|
if (grayData[py * w + x] < darkThresh)
|
||||||
cleanedData[py * w + x] = 255;
|
{
|
||||||
else
|
lastDark = x;
|
||||||
break;
|
skipCount = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
skipCount++;
|
||||||
|
if (skipCount > tolerance) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int x = 0; x <= lastDark; x++)
|
||||||
|
cleanedData[py * w + x] = 255;
|
||||||
}
|
}
|
||||||
// 右边缘
|
// 右边缘
|
||||||
for (int py = 0; py < h; py++)
|
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--)
|
for (int x = w - 1; x >= Math.Max(0, w - maxScanDepth); x--)
|
||||||
{
|
{
|
||||||
if (grayData[py * w + x] < darkThresh)
|
if (grayData[py * w + x] < darkThresh)
|
||||||
cleanedData[py * w + x] = 255;
|
{
|
||||||
else
|
lastDark = x;
|
||||||
break;
|
skipCount = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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);
|
Marshal.Copy(cleanedData, 0, cleaned.Data, cleanedData.Length);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user