车牌定位--颜色分割

http://blog.csdn.net/liujia2100/article/details/30845493

车牌定位是车牌识别中第一步,也是最重要的一步。

由于中国车牌种类多样,颜色不一, 再加上车牌经常有污损,以及车牌周围干扰因素太多,都成为了车牌定位的难点。

这里首先使用最简单算法来描述车牌定位,以及他的缺陷和改进。

一、投影法

1、车辆图像信息获取

2、HSV颜色转换

把RGB数据转换成HSV空间图像数据

hsvzation(image,hsv,width,height);

3、HSV颜色过滤

设置蓝色车牌底色阈值范围,进行颜色过滤

蓝色车牌

H值范围:190 ~ 245

S值范围: 0.35 ~ 1

V值范围: 0.3 ~ 1

过滤后图像如下:

4、噪声处理

过滤后,一般要进行去噪处理,这里早点不明显,如果车牌周围有蓝色物体,噪点就非常明显了

这里使用平均去噪,一些孤立白点将被去除,效果如下:

5、边缘检测

去噪后,进行边缘检测,边缘检测的目的就是为了突出车牌信息的突变,因为车牌背景和字体颜色区分开了;

这样做的目的也是为了防止周围有和车牌底色相同颜色的物体干扰,尤其是车辆颜色,因为经过边缘检测后车体颜色没有那么多跳变干扰或者与车牌跳变规律不一样,这样就可以滤去车体颜色,去除干扰

6、确定车牌位置

通过水平投影和垂直投影确定车牌位置。

(这里投影方法有很大缺陷,在车牌周围除了车辆还有其他背景信息时尤为明显,这在下面的另一种方法中改善)

7、截取车牌图像

二、投影法定位缺陷示例

1、读取复杂背景的车牌图像

2、HSV滤波

HSV过滤后可以看到明显的干扰信息,车辆后面的栏杆,和车辆同样的颜色

3、均值去噪

去噪后,虽然大部分噪点都去除了,但是栏杆依然清晰

4、边缘检测

边缘检测后的图像,车牌区域的形状特征,给我们解决投影缺陷的一些启示

5,、 投影后错误的定位

6、车牌提取错误

后半块车身,比例也不符合车牌特征

由此看见,在复杂背景的车牌识别中,全局投影就无法抑制干扰,在下面黄色车牌示例中就更加明显;

投影法简单,但只是在只有整体车辆信息,没有复杂背景信息的时候才可以使用。

三、基于候选区域判断方法

这个方法放弃了投影,直接遍历整个图像信息,检查每个联通域的长度和宽度,当符合车牌的宽高比时,才选定为候选区域,由后面处理流程进行处理,来判断是否能够提取正常的字符。

前两个步骤还是同上面一样的。

1、HSV空间转换

2、均值去噪

3、水平膨胀

目的:尽可能的形成连通域

4、边缘检测

也可以不用边缘检测,这里主要考虑到 尽量减少 图像白点 遍历中的运算

5、候选区域筛选

候选区域筛选, 这是区别投影方法的主要部分,

从上图可以看出有几个候选区域,大概有4块, 而中间的车牌有明显矩形特征,符合一定的长宽比例, 其他三块区域不具备这样的特征,在筛选的过程中予以舍弃。

筛选的方法采用 深度优先遍历, 当遇到连通域时,记录他的长度和高度,并设定阈值,当符合长宽比时,才会选中为候选区域,否则予以舍弃,当然还可以添加别的算法,比如检测跳变,毕竟符合这一比率的不一定就是车牌区域。

下图中黄框就是筛选后的区域:

连通域筛选函数如下:

[cpp] view plaincopy

  1. int find_connected_region_location(struct BMP_img *img, unsigned char *src, int xthreashold, int ythreashold, float rateLow, float rateHigh)
  2. {
  3. int i,j;
  4. int x1, y1, x2, y2;
  5. int width;
  6. int height;
  7. unsigned char *temp;
  8. //int queue_count;
  9. int head, rear;
  10. struct XY_Queue *queue;
  11. static int direction[4][2]={{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
  12. width = img->width;
  13. height = img->height;
  14. queue = (struct XY_Queue *)malloc(sizeof(struct XY_Queue) * width * height);
  15. temp = (unsigned char *)malloc(width * height * sizeof(unsigned char));
  16. if(temp == NULL)
  17. {
  18. printf("find_connected_region_location mem alloc fail\n");
  19. return -1;
  20. }
  21. memcpy(temp, src, width * height);
  22. head = rear = 0;
  23. img->region_num = 0;
  24. for(i = 0; i < height; i++)
  25. for(j = 0; j < width; j++)
  26. {
  27. if(temp[i * width + j] == 255)
  28. {
  29. queue[rear].x = j;
  30. queue[rear].y = i;
  31. rear ++;
  32. temp[i * width + j] = 0;
  33. img->pre_region[img->region_num].x1 = j;
  34. img->pre_region[img->region_num].x2 = j;
  35. img->pre_region[img->region_num].y1 = i;
  36. img->pre_region[img->region_num].y2 = i;
  37. if(img->region_num > CAN_REGION_NUM)
  38. {
  39. printf("over the CAN_REGION_NUM\n");
  40. return -1;
  41. }
  42. while(head < rear)
  43. {
  44. x1 = queue[head].x;
  45. y1 = queue[head].y;
  46. head ++;
  47. if(x1 < img->pre_region[img->region_num].x1)
  48. img->pre_region[img->region_num].x1 = x1;
  49. else if(x1 > img->pre_region[img->region_num].x2)
  50. img->pre_region[img->region_num].x2 = x1;
  51. if(y1 < img->pre_region[img->region_num].y1)
  52. img->pre_region[img->region_num].y1 = y1;
  53. else if(y1 > img->pre_region[img->region_num].y2)
  54. img->pre_region[img->region_num].y2 = y1;
  55. for(i = 0; i < 4; i++)
  56. {
  57. x2 = x1 + direction[i][0];
  58. y2 = y1 + direction[i][1];
  59. if(x2 > 0 && x2 < width && y2 > 0 && y2 < height && temp[y2 * width + x2])
  60. {
  61. temp[y2 * width + x2] = 0;
  62. queue[rear].x = x2;
  63. queue[rear].y = y2;
  64. rear ++;
  65. }
  66. }
  67. }
  68. if((img->pre_region[img->region_num].x2 - img->pre_region[img->region_num].x1 > xthreashold) && (img->pre_region[img->region_num].y2 - img->pre_region[img->region_num].y1 > ythreashold))
  69. {
  70. img->pre_region[img->region_num].width = img->pre_region[img->region_num].x2 - img->pre_region[img->region_num].x1 + 1;
  71. img->pre_region[img->region_num].height = img->pre_region[img->region_num].y2 - img->pre_region[img->region_num].y1 + 1;
  72. img->pre_region[img->region_num].rate = (float)img->pre_region[img->region_num].width/img->pre_region[img->region_num].height;
  73. if((img->pre_region[img->region_num].width < img->width / 2) && (img->pre_region[img->region_num].height < img->height / 2))
  74. if((img->pre_region[img->region_num].rate > rateLow) && (img->pre_region[img->region_num].rate < rateHigh))
  75. {
  76. if(img->pre_region[img->region_num].x2 + PRE_LOCATION_BIAS > img->width)
  77. img->pre_region[img->region_num].x2 = img->width;
  78. else
  79. img->pre_region[img->region_num].x2 += PRE_LOCATION_BIAS;
  80. if(img->pre_region[img->region_num].x1 - PRE_LOCATION_BIAS < 0)
  81. img->pre_region[img->region_num].x1 = 0;
  82. else
  83. img->pre_region[img->region_num].x1 -= PRE_LOCATION_BIAS;
  84. if(img->pre_region[img->region_num].y2 + PRE_LOCATION_BIAS > img->height)
  85. img->pre_region[img->region_num].y2 = img->height;
  86. else
  87. img->pre_region[img->region_num].y2 += PRE_LOCATION_BIAS;
  88. if(img->pre_region[img->region_num].y1 - PRE_LOCATION_BIAS < 0)
  89. img->pre_region[img->region_num].y1 = 0;
  90. else
  91. img->pre_region[img->region_num].y1 -= PRE_LOCATION_BIAS;
  92. img->pre_region[img->region_num].width = img->pre_region[img->region_num].x2 - img->pre_region[img->region_num].x1 + 1;
  93. img->pre_region[img->region_num].height = img->pre_region[img->region_num].y2 - img->pre_region[img->region_num].y1 + 1;
  94. img->region_num++;
  95. }
  96. }
  97. }
  98. }
  99. free(temp);
  100. temp = NULL;
  101. return 0;
  102. }

6、截取车牌区域图像

四、黄色车牌检测

1、车辆图像信息

2、HSV过滤分割

由于车牌颜色 与 车辆颜色一直,出现大量噪声信息,全局投影已不可能分割出车牌信息了,

这里只是 利用候选区域长宽比来进行矩形分割,肯定会出现一些符合比例但是不是车牌的区域,必须在后面的处理中加以区分或者添加判断跳变规律的函数

3、去噪

4、 膨胀

6、边缘检测

7、候选区域 连通域筛选

从图中可以看到黄框 部分即是符合候选区域的地方

8、截取候选区域

此候选区域只是符合长宽比,需要另行处理 除去不是车牌的区域

五、小结

车牌定位比较复杂,但对于车牌识别来说,最为重要,我认为它是影响车牌识别最大因素。虽然复杂,但是方法多种多样。

这里仅此个人爱好和研究,希望各位朋友继续提出批评和建议,大家的鼓励给了我坚持下去的勇气。

更希望能够一起去讨论:

QQ群:105060236105060236

时间: 2024-10-11 12:03:14

车牌定位--颜色分割的相关文章

【原】基于matlab的蓝色车牌定位与识别---绪论

本着对车牌比较感兴趣,自己在课余时间摸索关于车牌的定位与识别,现将自己所做的一些内容整理下,也方便和大家交流. 考虑到车牌的定位涉及到许多外界的因素,因此有必要对车牌照的获取条件进行一些限定: 一.大部分车牌照都是用自己的手机照的,大小在1M左右,距离车牌照距离3m左右.这样保证所获取的车牌照有一定的规律,否则随便一张是无法进行定位的. 二.本次仅针对蓝色车牌,至于其他像黄色,黑色车牌的没有做研究.感兴趣的可以自己找些资料,毕竟要做到全面,工作量还是很大的. 三. 相关的参考资料网上也挺多的,这

汽车车牌定位识别系统的设计实现

http://www.eeworld.com.cn/qrs/2015/1023/article_25403.html 一.项目背景及可行性分析 2.1 项目背景及技术难点 项目名称:智能交通:汽车车牌定位识别: 项目内容:本项目是在FPGA前端实时完成图像采集.预处理.车牌定位和字符分割以及数据传输工作,在后端完成车牌字符识别工作.FPGA接收采集的实时图像,在内部采用流水线方式依次完成图像预处理.车牌定位和车牌字符分割工作,最后通过高速USB端口将已分割字符传输到后端进行字符识别.其中,图像采

【原】基于matlab的蓝色车牌定位与识别---定位

接着昨天的工作继续.定位的过程有些是基于车牌的颜色进行定位的,自己则根据数字图像一些形态学的方法进行定位的. 合着代码进行相关讲解. 1.相对彩色图像进行灰度化,然后对图像进行开运算.再用小波变换获取图像的三个分量.考虑到车牌的竖直分量较为丰富,选用竖直分量进行后续操作.注意下,这里的一些参数可能和你的图片大小有关,所以要根据实际情况调整. Image=imread('D:\1_2学习\图像处理\车牌识别\matlab_car_plate-recognization\car_example\ca

基于matlab的蓝色车牌定位与识别---识别

接着昨天的工作,把最后一部分识别讲完. 关于字符识别这块,一种最省事的办法是匹配识别,将所得的字符和自己的标准字符库相减,计算所得结果,值最小的即为识别的结果.不过这种方法是在所得字符较为标准的情况,由于众多因素影响,切割出来的字符往往不是标准的,因此识别效果也不好.本次采用的BP神经网络方法,至于像其他的分类器方法,没有尝试,这里就不说了. 利用神经网络的方法的思路也比较清晰,将已有的字符库输入到神经网络的输入口进行训练,然后用训练好的神经网络对待识别的字符继续识别,输出识别结果.matlab

OpenCV使用边缘提取、腐蚀、轮廓进行车牌定位

采用OpenCV249利用边缘检测.轮廓检测.腐蚀实现的车牌定位,具体为: Mat srcImage=imread("image/000.jpg"); //imshow("a",srcImage); int i,j; int cPointR,cPointG,cPointB,cPoint;//currentPoint; Mat resizeImage; resize(srcImage,resizeImage,Size(400,300)); Mat grayImage;

EasyPR--中文开源车牌识别系统 开发详解(2)车牌定位

这篇文章是一个系列中的第三篇.前两篇的地址贴下:介绍.详解1.我撰写这系列文章的目的是:1.普及车牌识别中相关的技术与知识点:2.帮助开发者了解EasyPR的实现细节:3.增进沟通. EasyPR的项目地址在这:GitHub.要想运行EasyPR的程序,首先必须配置好openCV,具体可以参照这篇文章. 在前两篇文章中,我们已经初步了解了EasyPR的大概内容,在本篇内容中我们开始深入EasyRP的程序细节.了解EasyPR是如何一步一步实现一个车牌的识别过程的.根据EasyPR的结构,我们把它

OpenCVSharp对图像进行颜色分割

使用OpencvSharp的InRange函数对图像进行RGB颜色的分割. 1 using System; 2 using OpenCvSharp; 3 using OpenCvSharp.Extensions; 4 using OpenCvSharp.XFeatures2D; 5 using static OpenCvSharp.Cv2; 6 namespace Mycv 7 { 8 public class cvGO 9 { 10 /// <summary> 11 /// 分割颜色得到面积

基于matlab的蓝色车牌定位与识别---分割

接着上面的工作,接下去就该是进行字符分割了.考虑到为了后面的字符识别,因此在这部分需要实现的目标是需要把车牌的边框全部切除,对重新定位的车牌进行垂直方向水平方向调整,保证字符是正的.最后才是字符的分割. 1.首先上下边框切割.对定位的车牌每行作一次的差分,计算每行的综合,小于某个阈值时候将其舍去.部分代码: [length height]=size(p); % 水平方向定位 for i=1:length % 水平一阶差分 for j=1:height-1 revise_row(i,j)=abs(

车牌识别(一)-车牌定位

在对车牌识别过程中,常用的方法有:基于形状.基于色调.基于纹理.基于文字特征等方法.首先基于形状,在车牌中因为车牌为形状规格的矩形,所以目的转化为寻找矩形特征,常常是利用车牌长宽比例特征.占据图像的比例等.基于色调,国内的车牌往往是蓝底白字,可以采用图像的色调或者饱和度特征,进入生成二值图,定位车牌位置.基于纹理特征自己还没有基础到.基于文字特征往往是根据文字轮廓特征进行识别,原理是基于相邻文字轮廓特征.比例进行定位车牌位置. 一.图像二值化 正如前面文章所言,首先进行获取图像二值化特征,本文采