新增边缘阴影清除:从四边向内扫描暗像素区域推白
除法归一化对均匀阴影免疫,但边缘深色阴影的bg也被拉低, 除法后比值偏低变灰色。在最终LUT之后加入边缘扫描: 从上下左右四边向内逐列/行扫描原始灰度,低于纸面亮度60% 的连续暗像素设为纯白,遇到亮像素停止。最大扫描深度1/4。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -418,6 +418,77 @@ public static class DocumentScanner
|
||||
whiteLutMat.Dispose();
|
||||
sharpened.Dispose();
|
||||
|
||||
// --- g: 边缘阴影清除 ---
|
||||
// 从四边向内扫描原始灰度图,连续暗像素区域标记为阴影→纯白
|
||||
// 除法归一化对均匀阴影免疫,但边缘深色阴影bg也被拉低,
|
||||
// 除法后比值偏低变成灰色,需要额外清除
|
||||
int cx1 = w / 4;
|
||||
int cx2 = w * 3 / 4;
|
||||
int cy1 = h / 4;
|
||||
int cy2 = h * 3 / 4;
|
||||
long centerSum = 0;
|
||||
int centerCount = 0;
|
||||
for (int py = cy1; py < cy2; py++)
|
||||
{
|
||||
for (int px = cx1; px < cx2; px++)
|
||||
{
|
||||
centerSum += grayData[py * w + px];
|
||||
centerCount++;
|
||||
}
|
||||
}
|
||||
int paperBright = (int)(centerSum / Math.Max(centerCount, 1));
|
||||
int darkThresh = (int)(paperBright * 0.6);
|
||||
int maxScanDepth = Math.Max(w, h) / 4; // 最多扫描1/4深度
|
||||
|
||||
byte[] cleanedData = new byte[w * h];
|
||||
Marshal.Copy(cleaned.Data, cleanedData, 0, cleanedData.Length);
|
||||
|
||||
// 上边缘
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
for (int y = 0; y < Math.Min(maxScanDepth, h); y++)
|
||||
{
|
||||
if (grayData[y * w + x] < darkThresh)
|
||||
cleanedData[y * w + x] = 255;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 下边缘
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
for (int y = h - 1; y >= Math.Max(0, h - maxScanDepth); y--)
|
||||
{
|
||||
if (grayData[y * w + x] < darkThresh)
|
||||
cleanedData[y * w + x] = 255;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 左边缘
|
||||
for (int py = 0; py < h; py++)
|
||||
{
|
||||
for (int x = 0; x < Math.Min(maxScanDepth, w); x++)
|
||||
{
|
||||
if (grayData[py * w + x] < darkThresh)
|
||||
cleanedData[py * w + x] = 255;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 右边缘
|
||||
for (int py = 0; py < h; py++)
|
||||
{
|
||||
for (int x = w - 1; x >= Math.Max(0, w - maxScanDepth); x--)
|
||||
{
|
||||
if (grayData[py * w + x] < darkThresh)
|
||||
cleanedData[py * w + x] = 255;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
Marshal.Copy(cleanedData, 0, cleaned.Data, cleanedData.Length);
|
||||
|
||||
// 转回3通道
|
||||
Mat output = new Mat();
|
||||
Cv2.CvtColor(cleaned, output, ColorConversionCodes.GRAY2BGR);
|
||||
|
||||
Reference in New Issue
Block a user