上回书说道,我们对银行卡进行了一系列的预处理后,得到了下面的结果:
银行卡下半部分严重影响到了检测的效果,所以在进行机器学习前,我们还需要做一点处理,把下半部分的噪声给消除掉。
思路:首先,针对农行卡颜色的特点(目前暂时只讨论农行卡)上半部分颜色相对较浅,下半部分颜色较深,而银行卡号属深色,所以往往会出现上图所示的---下半部分大面积噪声,上半部分可能没有或者有细微的少量噪声的现象,故该图具有一定的普遍性。
如上图所示,实际上有效的检测区域就是上图红线之间的数字部分,其余部分均无效,于是乎,我们可以这样实现:
遍历整张二值图,统计每行的有效像素(黑色),若该行有效像素个数高于阈值则表示该行开始是有效区域,若该行有效像素个数低于阈值则表示该行无图像或者是噪声;检测到有效区域后开始,即找到了上面那条红线后,我们开始找下面那条红线的位置,若该行有效像素个数低于阈值,则表示检测到了无效区域,即检测到了下面的红线------如此一来我们便得到了有效区域的高度,我们将所有的无效区域清除即可。
关键代码实现:
IplImage *Filter(IplImage*imgSrc)
{//过滤图像
int a = 0, b = 0;//保存有效行号
int state = 0;//标志位,0则表示还未到有效行,1则表示到了有效行,2表示搜寻完毕
for (int y = 0; y < imgSrc->height; y++)
{
int count = 0;
for (int x = 0; x < imgSrc->width; x++)
{
if (cvGet2D(imgSrc, y, x).val[0] == 0)
count = count + 1;
}
if (state == 0)//还未到有效行
{
if (count >= 10)//找到了有效行
{//有效行允许十个像素点的噪声
a = y;
state = 1;
}
}
else if (state == 1)
{
if (count <= 10)//找到了有效行
{//有效行允许十个像素点的噪声
b = y;
state = 2;
}
}
}
for (int y = 0; y < imgSrc->height; y++)
{
if(y >= a && y <= b)
continue;
for (int x = 0; x < imgSrc->width; x++)
{
((uchar *)(imgSrc->imageData + y*imgSrc->widthStep))[x] = 255;
}
}
return imgSrc;
}
结果:
预处理到此完毕
机器学习下回分解。
<!--EndFragment-->