您的位置:首页 > 其它

实现-汽车牌照识别系统中车牌定位与校正及字符分割的研究

2013-04-07 20:35 751 查看
最近在看车牌识别相关领域的论文,自己也试验了一些开源的代码,opencv自带的找四边形的程序等等,感觉效果都不好。在车牌识别中,关键的是车牌定位,决定了车牌识别的准确率,目前研究比较多的也就是基于颜色、边缘、纹理的车牌定位方法,看了几篇论文,有一篇硕士论文叫《汽车牌照识别系统中车牌定位与校正及字符分割的研究》,南航的一位同学的硕士毕业论文,想实现其中的车牌定位算法。可以去网上搜索该论文,在道客巴巴上有。

论文中车牌定位的算法分为九步,我只实现了前三步,觉得不行,具体的一些实现代码如下:

/////////////////////////////////////////////////////////////////////////////
//1. 确定纹理特征点
////////////////////////////////////////////////////////////////////////////
int cal_texture_point(IplImage * src,IplImage * dst)
{
if(NULL == src || NULL == dst)
return 1;

IplImage * tempImage = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);

uchar * data = (uchar *)src->imageData;
uchar * result = (uchar *)tempImage->imageData;

int width = src->width;
int height = src->height;

for(int i = 0;i < src->height;i++)
for (int j = 0;j < src->width ;j++)
{
if(j == 0)
result[i * src->widthStep + j] = abs(int(data[i * src->widthStep + j]) - int(data[i * src->widthStep + j + 1]));
else if(j == width - 1)
result[i * src->widthStep + j] = abs(int(data[i * src->widthStep + j]) - int(data[i * src->widthStep + j - 1]));
else
result[i * src->widthStep + j] = abs(int(data[i * src->widthStep + j]) - int(data[i * src->widthStep + j + 1]))
+ abs(int(data[i * src->widthStep + j]) - int(data[i * src->widthStep + j - 1]));
}

cvCopy(tempImage,dst);
cvReleaseImage(&tempImage);

return 0;
}
//////////////////////////////////////////////////////////////////////////
//2.计算颜色边缘点
//
//
//////////////////////////////////////////////////////////////////////////
int cal_color_edge(IplImage * src,IplImage * bwImage,IplImage * blue,IplImage * white,IplImage * yellow,IplImage * black)
{
if(NULL == src)
return 1;

int width = src->width;
int height = src->height;
//计算HSV分量
int k1,k2,r,g,b,h;
float s,v;

cvZero(blue);
cvZero(white);
cvZero(yellow);
cvZero(black);

uchar * data = (uchar *)src->imageData;

uchar * blueD = (uchar *)blue->imageData;
uchar * whiteD = (uchar *)white->imageData;
uchar * yellowD = (uchar *)yellow->imageData;
uchar * blackD = (uchar *)black->imageData;
uchar * bwDate = (uchar *)bwImage->imageData;
for (int i = 0;i < height;i++)
{
for (int j = 0;j < width;j++)
{
if(bwDate[i * bwImage->widthStep + j] == 0)
continue;

r = (int)data[i * src->widthStep + j];
k1 = r;
k2 = r;

g = (int)data[i * src->widthStep + j + 1];
if(k1 < g)k1 = g;
if(k2 > g)k2 = g;
b = (int)data[i * src->widthStep + j + 2];
if(k1 < b)k1 = b;
if(k2 > b)k2 = b;

//计算hsv分量
v = 1.0 * (k1 + k2) / 2 / 255;

if(v == 0 || k1 == k2)
s = 0;
else if(v > 0.5)
s = 1.0 * (k1 - k2) / (2 - 2 * v);
else if(v <= 0.5)
s = 1.0 * (k1 - k2) / (2 * v);

if(s != 0 && k1 == r)
{
if(g >= b)
h = 1.0 * (g - b) / (k1 - k2) * 60;
else
h = 1.0 * (g - b) / (k1 - k2) * 60 + 360;
}
else if(s != 0 && k1 == g)
h = 1.0 * (b - r) / (k1 - k2) * 60 + 120;
else if(s != 0 && k1 == b)
h = 1.0 * (r - g) / (k1 - k2) * 60 + 240;
else if(k1 == k2)
h = 0;

if(h > 200 && h < 250 && s > 0.1 && v > 0.1)
blueD[i * blue->widthStep + j] = 255;
else if(h > 20 && h < 50 && s > 0.1 && v > 0.35)
yellowD[i * blue->widthStep + j] = 255;
else if(h == 0 && s ==0 && v < 0.35)
blackD[i * blue->widthStep + j] = 255;
else if(v > 0.5 && s < 0.1)
whiteD[i * blue->widthStep + j] = 255;
}
}

return 0;
}

//////////////////////////////////////////////////////////////////////////
//3. 计算三种颜色对特征点
//蓝白、黄黑、白黑特征点对
//例如:如果(i,j)点为蓝色点,对于(i,j)左右两侧的四个像素点,一旦其中一个点有白色像素,则记为蓝白像素点;
//同样白色点左右四个点有蓝色点也记为蓝白特征点对
//////////////////////////////////////////////////////////////////////////
int cal_color_point(IplImage * blue,IplImage * white,IplImage * yellow,IplImage * black,
IplImage * b_w_image,IplImage * y_b_image,IplImage * w_b_image)
{
int width = blue->width;
int height = blue->height;

cvZero(b_w_image);
cvZero(y_b_image);
cvZero(w_b_image);;

uchar * blueD = (uchar *)blue->imageData;
uchar * whiteD = (uchar *)white->imageData;
uchar * yellowD = (uchar *)yellow->imageData;
uchar * blackD = (uchar *)black->imageData;

uchar * y_b_data = (uchar *)y_b_image->imageData;
uchar * b_w_data = (uchar *)b_w_image->imageData;
uchar * w_b_data = (uchar *)w_b_image->imageData;
for (int i = 0;i < height;i++)
{
for (int j = 2;j < width - 2;j++)
{
//计算蓝白点
if(blueD[i * blue->widthStep + j] == 255)
{
for (int k = j - 2;k <= j + 2;k++)
{
if(whiteD[i * blue->widthStep + k] == 255)
b_w_data[i * blue->widthStep + j] = 255;
}
}

//计算蓝白点和白黑点
if(whiteD[i * blue->widthStep + j] == 255)
{
for (int k = j - 2;k <= j + 2;k++)
{
if(blueD[i * blue->widthStep + k] == 255)
b_w_data[i * blue->widthStep + j] = 255;
if(blackD[i * blue->widthStep + k] == 255)
w_b_data[i * blue->widthStep + j] = 255;
}
}
//计算黄黑点
if(yellowD[i * blue->widthStep + j] == 255)
{
for (int k = j - 2;k <= j + 2;k++)
{
if(blackD[i * blue->widthStep + k] == 255)
y_b_data[i * blue->widthStep + j] = 255;
}
}

//计算黄黑点和白黑点
if(blackD[i * blue->widthStep + j] == 255)
{
for (int k = j - 2;k <= j + 2;k++)
{
if(yellowD[i * blue->widthStep + k] == 255)
y_b_data[i * blue->widthStep + j] = 255;
if(whiteD[i * blue->widthStep + k] == 255)
w_b_data[i * blue->widthStep + j] = 255;
}
}
}
}

return 0;
}


函数调用代码如下:

void main()
{
IplImage * image = 0;
IplImage * gray = 0;
IplImage * bwImage = 0;

//计算颜色点
IplImage * blueImage;
IplImage * yImage;
IplImage * wImage;
IplImage * blackImage;

//计算颜色点对
IplImage * bandwImage;//蓝白特征点对
IplImage * yandbImage;//黄黑特征点对
IplImage * wandbImage;//白黑特征点对
image = cvLoadImage(files[i].c_str(),CV_LOAD_IMAGE_COLOR);
blueImage = cvCreateImage(cvSize(image->width,image->height),8,1);
yImage = cvCreateImage(cvSize(image->width,image->height),8,1);
wImage = cvCreateImage(cvSize(image->width,image->height),8,1);
blackImage = cvCreateImage(cvSize(image->width,image->height),8,1);

bandwImage = cvCreateImage(cvSize(image->width,image->height),8,1);
yandbImage = cvCreateImage(cvSize(image->width,image->height),8,1);
wandbImage = cvCreateImage(cvSize(image->width,image->height),8,1);

gray = cvCreateImage(cvSize(image->width,image->height),8,1);
bwImage = cvCreateImage(cvSize(image->width,image->height),8,1);

cvCvtColor(image,gray,CV_BGR2GRAY);

//1.计算纹理图像===============================
cal_texture_point(gray,gray);
//二值化纹理图片保存至bwImage
cvThreshold(gray,bwImage,0,255,CV_THRESH_OTSU);

//2.计算颜色特征点=============================
cal_color_edge(image,bwImage,blueImage,wImage,yImage,blackImage);

//3.计算颜色对特征点===========================
cal_color_point(blueImage,wImage,yImage,blackImage,bandwImage,yandbImage,wandbImage);

cvReleaseImage(&image);
cvReleaseImage(&gray);
cvReleaseImage(&bwImage);
cvReleaseImage(&blueImage);
cvReleaseImage(&wImage);
cvReleaseImage(&yImage);
cvReleaseImage(&blackImage);
}


原图:



结果图片为:

第一步的结果:纹理图片



第二步结果:顺序为:黑色点、蓝色点、白色点、黄色点









第三步结果:顺序为:蓝白特征对点、黄黑特征点对、黑白特征点对







而论文里边的处理结果确实很好,不知道在转HSV图片,以及各颜色分量的范围是如何确定的...按论文里边的范围得到的结果是不行的~~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: