新增条带状折痕检测:按列/行投影识别窄条暗带

深色窄折痕的边缘方差高(亮暗跳变),双级方差检测不到。
新增条带检测:按列/行统计暗像素比例,超过40%的列/行
标记为折痕条带,条带内低方差像素推白,高方差像素(文字)保留。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-19 17:06:01 +08:00
parent 473eeb6e53
commit f17fd5cb85

View File

@@ -461,13 +461,81 @@ public static class DocumentScanner
{
if (inkData[i] > 10 && varDataS[i] < 5 && varDataL[i] < 12)
{
// 两级方差都低 → 折痕/阴影
double suppressRatio = (double)varDataS[i] / 5.0;
int origVal = resultData[i];
resultData[i] = (byte)(origVal + (int)((255 - origVal) * (1.0 - suppressRatio)));
}
}
// --- 条带状折痕检测 ---
// 折痕特征:垂直或水平方向上,某列/行有大量连续暗像素
// 文字不会形成这种长条状连续暗区域
//
// 对每列统计暗像素比例,高比例的列标记为折痕条带
int inkThreshForStripe = 30; // 墨迹强度>30才算暗像素
double stripeRatioThresh = 0.4; // 一列中40%以上是暗像素就是条带
int stripeHalfWidth = 3; // 条带半宽左右各扩展3像素
// 垂直条带检测(按列扫描)
bool[] vStripe = new bool[w];
for (int x = 0; x < w; x++)
{
int darkCount = 0;
for (int y = 0; y < h; y++)
{
if (inkData[y * w + x] > inkThreshForStripe) darkCount++;
}
vStripe[x] = ((double)darkCount / h) > stripeRatioThresh;
}
// 水平条带检测(按行扫描)
bool[] hStripe = new bool[h];
for (int y = 0; y < h; y++)
{
int darkCount = 0;
for (int x = 0; x < w; x++)
{
if (inkData[y * w + x] > inkThreshForStripe) darkCount++;
}
hStripe[y] = ((double)darkCount / w) > stripeRatioThresh;
}
// 扩展条带宽度并抑制
for (int i = 0; i < resultData.Length; i++)
{
int x = i % w;
int y = i / w;
bool inStripe = false;
// 检查是否在垂直条带范围内
for (int dx = -stripeHalfWidth; dx <= stripeHalfWidth; dx++)
{
int nx = x + dx;
if (nx >= 0 && nx < w && vStripe[nx]) { inStripe = true; break; }
}
// 检查是否在水平条带范围内
if (!inStripe)
{
for (int dy = -stripeHalfWidth; dy <= stripeHalfWidth; dy++)
{
int ny = y + dy;
if (ny >= 0 && ny < h && hStripe[ny]) { inStripe = true; break; }
}
}
if (inStripe && inkData[i] > 5)
{
// 在条带内:检查这个像素是否真的是文字
// 文字在条带内的特征:小核方差高(笔画边缘锐利)
if (varDataS[i] < 10)
{
// 方差不高 → 不是文字,是折痕本身 → 推白
resultData[i] = 255;
}
// 方差高 → 是文字,保留不动
}
}
// --- 边缘阴影修复:从边缘向内扫描连续暗像素 ---
byte[] shadowFlag = new byte[w * h];
int darkThresh = (int)(paperBright * 0.55);