车牌识别算法实践(一):先验知识
一般来说,一个完整的车牌识别系统的处理流程包括图像输入、车牌提取、字符分割、字符识别和结果输出这五部分。其中车牌提取、字符分割和字符识别是较重要的部分,而车牌提取尤为关键,采用哪种算法或算法组合决定了整个系统的性能。
本人从多年前就开始研究车牌识别的各种算法,以资源需求低、运行高效和鲁棒性强为目标,在嵌入式系统中以C/C++实现了车牌识别的整个流程。本系统能同时识别出车牌类型和车牌号,能适应阴雨雪雾等低照度条件,对于倾斜、脏污、损伤、变形等车牌的识别率也很高。当时为了验证和演示,用VS2005做了一个测试工具。今以这个测试工具的源码为基础,分步骤地将我设计的车牌识别系统软件的重要算法分享出来。源代码还含有不少调试的痕迹以及没有实际用到的算法在里面,待整理后会开放下载。欢迎技术探讨,WX:15380886180或Email:bhw98@sina.com。
为提高效率和准确率,在车牌识别流程的各个部分,要充分利用先验知识对算法的参数范围进行限制,例如车牌长宽比、车牌背景色、字符颜色、字符字体、字符行数、字符间隔分布特征、每个字符所属的字符集等。举个例子,车牌中的汉字个数很有限,做识别时只要在那么几十个字中搜索就行了,而没有必要在整个GB-2312字符集中进行搜索。
关于中国的车辆号牌种类的简明介绍,可参考百度百科:https://baike.baidu.com/item/%E8%BD%A6%E7%89%8C/8347320?fr=aladdin。更详细、更专业的资料请参照公安部发布的GA36-2018标准文件。
对于颜色来说,理论上红、绿、蓝、黄、黑、白等,其RGB或HSV值都有标准定义。但对于实际拍摄的图像,由于受环境光和拍摄手法的影响,颜色都会或多或少带有“污染”。例如,下图左边的车牌受强光刺激,底色变为青色(绿色分量较多);右边的车牌在弱光环境中受车灯影响,底色和字符色都含有相当多的红色分量。那么判断底色为“蓝色”的标准是什么?这就需要根据足够多的样本来确定阈值(机器学习的训练过程不包含在本车牌识别系统中)。这种阈值也是一种先验知识。
泛泛地说,各种常量定义都可以理解为先验知识的合理运用。在后续章节中也会有一些先验知识(常量定义)的介绍。
对于车牌样式(种类)的参数,定义了如下的结构:
typedef struct PARAMS
{int num_row; // 字符行数int num_charset; // 字符集个数int alpha_style; // 字母、数字样式int hanzi_style; // 汉字样式int ratio0; // 正常字符间距之间的比例的下限int ratio1; // 正常字符间距之间的比例的上限,分隔点前、后两字符间距与正常字符间距的比例的下限int ratio2; // 分隔点前、后两字符间距与正常字符间距的比例的上限,正常字符倍间距与倍间距的比例的下限int ratio3; // 正常字符倍间距与倍间距的比例上限,分隔点前、后两字符加字符间距与正常字符间距的比例的的下限int ratio4; // 分隔点前、后两字符加字符间距与正常字符间距的比例的的上限,正常字符倍间距与倍间距的比例的下限int ratio5; // 正常字符倍间距与倍间距的比例的上限struct {int num_sym; // 字符个数(不含分隔符)int septor_pos; // 分隔符的位置int septor_style; // 分隔符样式int back_color0; // 分隔符前的背景颜色int back_color; // 分隔符后的背景颜色int fore_color; // 主要的字符颜色int fore_color1; // 最末位字符颜色int width; // 字符宽度int height; // 字符高度int x_space; // 正常字符间距int x_dot_space; // 分隔点前、后两字符间距int y_center; // 中央y坐标int x_center[NUM_SYMBOL]; // 各字符中央x坐标int charset[NUM_SYMBOL]; // 各字符所属字符集int sequence[NUM_SYMBOL]; // 易识别字符的序号, 以结束} row[2]; // 每行的参数 char chars[NUM_CHARSET][64]; // 字符集的定义
} PARAMS;
有关常量定义如下:
const int NUM_SYMBOL = 12; // 车牌中字符个数的最大值
const int NUM_CHARSET = 4; // 车牌中字符集个数的最大值
车牌提取处理后,车牌区域的图像会归一化到相同的尺寸(像素值),定义如下:
const int WP = 384; // 透视变换的车牌宽度
const int HP = 116; // 透视变换的车牌高度
以小型汽车(蓝底白字)的参数定义为例,加以说明。
static const PARAMS params[] =
{… …{ // 小型汽车,蓝底白字1, // 字符行数3, // 字符集个数ALPHA_OLD, // 字母、数字样式HANZI_OLD, // 汉字样式80, // 正常字符之间间距的比例的下限120, // 正常字符之间间距的比例的上限,分隔点前、后两字符间距与正常字符间距的比例的下限170, // 分隔点前、后两字符间距与正常字符间距的比例的上限,正常字符倍间距与倍间距的比例的下限220, // 正常字符倍间距与倍间距的比例上限,分隔点前、后两字符加字符间距与正常字符间距的比例的的下限270, // 分隔点前、后两字符加字符间距与正常字符间距的比例的的上限,正常字符倍间距与倍间距的比例的下限320, // 正常字符倍间距与倍间距的比例的上限{{7, // 字符个数(不含分隔符)2, // 分隔符的位置SEPTOR_DOT, // 分隔符样式BLUE, // 分隔符前的背景颜色BLUE, // 分隔符后的背景颜色WHITE, // 主要的字符颜色WHITE, // 最末位字符颜色40, // 字符宽度80, // 字符高度51, // 正常字符间距71, // 分隔点前、后两字符间距58, // 中央y坐标{30, 81, 152, 203, 254, 305, 356}, // 各字符中央x坐标{2, 0, 1, 1, 1, 1, 1}, // 各字符所属字符集{3, 2, 4, 6, 0, 1, 5}, // 易识别字符的序号}, // 第一行的参数},{"ABCDEFGHJKLMNPQRSTUVWXYZ","0123456789ABCDEFGHJKLMNPQRSTUVWXYZ","\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E",}, // 字符集的定义},… …
};
有关常量定义如下:
enum
{BLACK, // 黑色WHITE, // 白色RED, // 红色GREEN, // 绿色BLUE, // 蓝色YELLOW, // 黄色
};enum
{HANZI_OLD, // 汉字字体
};enum
{ALPHA_OLD, // 英数字体, 蓝底白字、黄底黑字等车牌的英数字体ALPHA_NEW, // 英数字体,新能源车牌的英数字体
};enum
{SEPTOR_NONE, // 空白分隔符SEPTOR_DOT, // 圆点分隔符SEPTOR_DASH, // 横杠分隔符SEPTOR_PLUG, // 插头分隔符
};
字符行数num_row为1,这很明显。后面每行的参数row就只需要定义row[0]就行了,也就是第一行。
字符集个数num_charset为3。后面的二维数组chars有这3个字符集的定义(字符列表): "ABCDEFGHJKLMNPQRSTUVWXYZ", "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ", "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E",分别是纯字母、字母加数字和汉字。注意字母表中是没有‘I’和‘O’的。汉字用的自定义单字节编码,从’\x80’开始,定义如下所示(”京”对应’\x80’,”津”对应’\x81’……)。
static WCHAR hanzi[] = L"京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新港澳使领学警渣挂";
各字符所属字符集charset为{2, 0, 1, 1, 1, 1, 1},是说首字符属于字符集2(汉字),下一个字符属于字符集0(纯字母),后面5个字符都属于字符集1(字母加数字)。
字符个数(不含分隔符)num_sym为7,共7个字符。
分隔符的位置septor_pos为2,是指在两个字符之后(或者说序号从0开始的第2个字符之前)。
分隔符样式septor_style为SEPTOR_DOT,是圆点分隔符。
分隔符前的背景颜色back_color0分隔符后的背景颜色back_color均为BLUE。如果是大型新能源汽车号牌,分隔符前后的背景颜色就不同了。
主要的字符颜色fore_color和最末位字符颜色fore_color1均为WHITE。如果是警车号牌,主要的字符颜色是黑色,最末位字符颜色是红色。
字符宽度width为40,字符高度height为80,正常字符间距x_space为51,分隔点前、后两字符间距x_dot_space为71,中央y坐标y_center为58,各字符中央x坐标x_center为{30, 81, 152, 203, 254, 305, 356}。这些参数都是基于车牌归一化尺寸384 x 116而定义的。
上述间距的参数是”标准”定义,实际处理时允许在一定的范围内波动,或者在一定范围内执行搜索。这就是ratio0到ratio5的意义所在了。ratio0代表正常字符间距之间的比例的下限,ratio1代表正常字符间距之间的比例的上限以及分隔点前、后两字符间距与正常字符间距的比例的下限,ratio2代表分隔点前、后两字符间距与正常字符间距的比例的上限以及正常字符倍间距与倍间距的比例的下限,ratio3代表正常字符倍间距与倍间距的比例上限以及分隔点前、后两字符加字符间距与正常字符间距的比例的下限,ratio4代表分隔点前、后两字符加字符间距与正常字符间距的比例的上限以及正常字符倍间距与倍间距的比例的下限,ratio5代表正常字符倍间距与倍间距的比例的上限。听着很拗口,其实好理解,就是正常字符间距、正常字符间距2倍、分隔点前后字符间距、分隔点前后字符间距2倍的下限、上限与相应间距的百分比。这些数值都是百分数取整。如ratio1为120表示120%,是说正常字符间距最大允许在51的基础上乘以120%,等于61。而这个数值同时也是分隔点前、后两字符间距与正常字符间距的比例的最小值(”标准值”是71,见上)。
字母、数字样式alpha_style为ALPHA_OLD。如果是新能源汽车号牌,就要用ALPHA_NEW了。
汉字样式hanzi_style为HANZI_OLD。实际上目前也就这一种字体。
车牌识别算法实践(一):先验知识相关推荐
- 车牌识别算法介绍与实践(转)
源: 车牌识别算法介绍与实践 转载于:https://www.cnblogs.com/LittleTiger/p/10101820.html
- 快准狠!Intel论文揭示自家车牌识别算法:LPRNet
(关注52CV--有价值有深度的公众号~) 来自工业界的最佳实践. 车牌识别是一个老生常谈的话题,在工业界已经得到广泛应用.当深度学习在各种视觉识别任务上刷新更高精度的时候,却常常被认为计算量远大于传 ...
- 【XLPNet车牌识别算法】第二章 检测部分-算法篇1
[XLPNet车牌识别算法]第二章 检测部分-算法篇1 1. XLPNet检测算法前言 2. XLPNet检测算法详解 2.1 起源 2.2 算法细节 2.1 算法命名 2.2 数据集 2.3 预备知 ...
- 寻找连通域算法_【车牌识别算法】
车牌识别技术要求能够将运动中的汽车牌照从复杂背景中提取并识别出来,通过车牌提取.图像预处理.特征提取.车牌字符识别等技术,识别车辆牌号.颜色等信息. 目前车牌识别技术主要分为端到端识别与车牌分割识别两 ...
- otsu算法_【车牌识别算法】
车牌识别技术要求能够将运动中的汽车牌照从复杂背景中提取并识别出来,通过车牌提取.图像预处理.特征提取.车牌字符识别等技术,识别车辆牌号.颜色等信息. 目前车牌识别技术主要分为端到端识别与车牌分割识别两 ...
- 车牌识别算法_易泊车牌识别算法助力智慧城市交通
引 言 随着科学技术的进步,智慧化的出现让现在生活越来越美,智慧城市.智慧交通等,今天我们的PC端车牌识别,也成为了智慧城市,智慧交通的一份子. 江西山水光电,他们在做智慧城市,目前他们做的一款巡逻车 ...
- 卷积神经网络算法python实现车牌识别_车牌识别算法之CNN卷积神经网络
原标题:车牌识别算法之CNN卷积神经网络 随着我国经济的发展,汽车,特别是小轿车的数量越来越多,智能交通管理系统应运而生.车牌智能自动识别作为智能交通管理系统中的重要组成部分,在智能交通管理中发挥着越 ...
- 国内的车牌识别算法怎样选择
出行必备工具汽车在方便人们出行的同时,导致了车辆的管理问题大幅度提升: 汽车的数量与车辆管理人员的随着时间的发展形成一个很大的漏洞.从而有了车牌识别SDK助力电子眼.移动警务.现场查勘等活动,减轻了工 ...
- 基于模板匹配的车牌识别算法,输出数字和英文字母
目录 一.理论基础 二.核心程序 三.仿真结论 一.理论基础 车牌识别是计算机视觉领域中的一个重要问题,其目的是从图像中自动识别出车辆的车牌信息.基于模板匹配的车牌识别算法是一种常见的方法,其基本思想 ...
- 车牌识别算法_PC端车牌识别SDK融入好算法
PC端车牌识别SDK介绍 易泊PC端车牌识别SDK融合了车牌定位.车牌字符切分.车牌字符识别等算法,使该系统具有识别效率高.速度快.适应性强.使用方便等优势,技术处于国际先进水平.大力发展机器人.人工 ...
最新文章
- 30分钟内让你明白正则表达式是什么,并对它有一些基本的了解(二)
- 复习下mybatis 中 useGeneratedKeys 和 keyProperty 含义
- 你可能不清楚的 Vue Router 深度用法(一)
- python基础之内建函数(二)
- 【Linux系统编程】POSIX有名信号量
- 网络4/7层模型各层作用和协议对比
- 面试云计算岗位时这些面试题不能错过
- JAVA 1.7并发之LinkedTransferQueue原理理解
- Vray渲染器和Corona渲染哪个更好用?
- 深度linux 无线网卡,在Deepin Linux系统无线网卡、蓝牙模块驱动安装和出现问题的解决...
- Linux配置阿里yum源
- php网页框架模板,用PHP制作静态网站的模板框架(四)
- 凡刻(Fenke)FK169机械手表测评
- 产品经理vs项目经理?四类PM区别都在这里啦
- MySQL必知必会!!!看这一篇就足够了!!!
- 傅立叶变换的原理、意义以及如何用Matlab实现快速傅立叶变换
- 【Mapreduce】Mapreduce实例——WordCount
- OpenCV-飞龙绣球识别
- eai java_关于EAI,ETL与EII
- 《Python程序设计(第3版)》[美] 约翰·策勒(John Zelle) 第 5 章 答案