車牌識別中,每一步的效果直接影響整體的識別率,對車牌識別產生干擾的,不僅是車牌的污漬,還有鉚釘。
一 、舉例說明,鉚釘干擾使得車牌識別錯誤
1、車輛圖片
2、通過顏色HSV確認車牌大致位置
3、截取車牌圖像
4、二值化後,水平投影,從圖片中可以很清楚看到鉚釘
5、字符分割後的車牌
6、提取分割後的車牌字符
7、錯誤的識別結果
二、改善方法
這裏針對車牌識別的干擾去除方法加以改善。
1、原先博文中車牌識別中去除鉚釘的方法,只是用投影的方法。粗略計算鉚釘在車牌的上方,白點信息較少,通過水平投影計算每一行的白點數
但是當鉚釘嵌入字符中間時,仍然無法去除干擾。
2、這裏採用直接出去鉚釘的方法,
1)、首先儘量分離字符與鉚釘的鏈接
2)、計算每行的跳變次數,一邊鉚釘所在行,都是兩次,不大於3次,超過7次的,就是字符區域所在行。
這裏使用的方法是在跳變次數小於5的行裏面,全局搜索白點,然後計算它的寬度和高度,如果寬度大於15個像素,高度大於25個像素(這裏車牌歸一化後字符大小爲20X40),那麼他就不是鉚釘,否則就當做鉚釘刪掉。
全局遍歷代碼:
for(i = 0; i < img->height/3; i++)
{
if(PointChg[i] && PointChg[i] < 5)//每行跳變次數
{
for(j = 0; j < img->width; j++)
{
if(dst[i * img->width + j] >= 200 && flag1 == 0)//發現白點即遍歷
{
x1 = x2 = j;
y1 = y2 = i;
delRivet(img, dst, &flag, j, i, &x1, &y1, &x2, &y2, 15, 25);
//display8(*img, dst, 0, 0);
flag1 = 1;
}
if(dst[i * img->width + j] == 0 && flag1 == 1)
{
flag1 = 0;
}
}
break;
}
}
刪除鉚釘的函數
img:用了記錄車牌的寬度高度信息等
dst:是二值化後的車牌信息,即要遍歷查找鉚釘的空間
*flag:用來標誌是不是鉚釘
*x1, *x2 用來計算鉚釘寬度 *x2-*x1;
*y1, *y2 同上
xlength,ylength,設置鉚釘寬度高度閾值。
static int direction[4][2]={{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int delRivet(Bmp1 *img, byte *dst, int *flag, int x, int y, int *x1, int *y1, int *x2, int *y2, int xlength, int ylength)
{
int i;
int tmp;
int x0, y0;
tmp = dst[y * img->width + x];
if((*x2 - *x1 > xlength) || (*y2 - *y1) > ylength)
{
*flag = 1;
return 0;
}
dst[y * img->width + x] = 0;
for(i = 0; i < 4; i++)
{
x0 = x + direction[i][0];
y0 = y + direction[i][1];
if(x0 > 0 && x0 < img->width && y0 > 0 && y0 < img->height && dst[y0 * img->width + x0] && (*flag == 0))
{
if(*x1 > x0)
*x1 = x0;
else if(*x2 < x0)
*x2 = x0;
if(*y1 > y0)
*y1 = y0;
else if(*y2 < y0)
*y2 = y0;
delRivet(img, dst, flag, x0, y0, x1, y1, x2, y2, xlength, ylength);
//display8(*img, dst, 0, 0);
}
}
if(*flag)
{
dst[y * img->width + x] = tmp;
}
return 0;
}
3)、去除鉚釘的車牌
4)、正確分割
5)、正確提取字符
6)、正確識別結果
源碼稍後,提供,車牌識別的代碼,我將繼續優化,提高識別率,儘早能夠應用在arm平臺上。