我稍微调整了一下你的输入
通过光照归一化和动态范围归一化,可以在一定程度上获得更好的结果,但仍然远离所需的效果。我想尝试锐化部分导数以增强字母与背景的对比,并在集成回来并重新着色掩码图像之前阈值处理小颗粒。如果有时间(不确定是何时,或许是明天),我会进行编辑(并评论/通知您)。
光照归一化
计算平均角落强度,并双线性地重新缩放强度以匹配平均颜色。
如果您需要更复杂的内容,请参见:
边缘检测
通过x
和y
的强度的部分导数 i
...
i=|i(x,y)/dx|+|i(x,y)/dy|
然后通过treshold=13
进行阈值处理。
[注]
为了消除大部分噪点,在边缘检测之前我应用了平滑滤波。
[编辑1] 经过一些分析,我发现您的图像对于锐化集成来说边缘很差
这是图像中间线经过x方向第一次导数后的强度图示例
如您所见,黑色区域很好,但白色区域几乎无法从背景噪声中识别出来。因此,您唯一的希望是像@Daniel的答案建议的那样使用最小最大滤波,并在黑色边缘区域上取更多权重(白色不可靠)。
最小最大滤波强调黑色(蓝色掩码)和白色(红色掩码)区域。如果两个区域都可靠,则只需填充它们之间的空间,但在您的情况下这不是一个选项,相反,我会扩大这些区域(更多地加权蓝色掩码),并使用为此类三色输入定制的OCR对结果进行OCR。
您还可以拍摄2张具有不同光照位置和固定相机的图像,并将它们合并以覆盖所有可识别的黑色区域。
[编辑2] 上述方法的C++源代码
typedef union color;
picture pic0,pic1,pic2;
void filter()
for (y=0;y<pic1.ys;y++)
for (x=0;x<pic1.xs;x++)
pic1.rgb_smooth();
pic2=pic1; pic2.clear(0);
pic2.bmp->Canvas->Pen ->Color=clWhite;
pic2.bmp->Canvas->Brush->Color=clWhite;
for (y=0;y<pic1.ys;y++)
for (x=0;x<pic1.xs;x++)
if (c==0x000000FF)
}
}
int picture::ui_normalize(int sz=32)
for (c0=0,c1=0,y=0;y<ys;y++)
for (x=0;x<xs;x++)
for (y=0;y<ys;y++)
for (x=0;x<xs;x++)
c=((p[y][x].dd-c0)*765)/(c1-c0);
return cavg;
}
void picture::rgb_smooth()
}
}
我使用自己的图片类来处理图片,其中一些成员包括:
xs,ys
:图片的尺寸(以像素为单位)
p[y][x].dd
:表示在(x,y)
位置上的像素,类型为32位整数
clear(color)
:清除整个图片
resize(xs,ys)
:将图片调整为新的分辨率
bmp
:VCL封装的GDI位图,可访问画布
我只添加了2个相关成员函数的源代码(不需要复制整个类)。
[编辑3] LQ 图片
我找到了最佳设置(代码相同):
int sz=32;
int fs0=2;
int fs1=2;
int tr0=52;
int tr1=0;
由于光线条件,红色区域无法使用(已关闭)。