EasyPR源码剖析(7):车牌判断之SVM
前面的文章中我们主要介绍了车牌定位的相关技术,但是定位出来的相关区域可能并非是真实的车牌区域,EasyPR通过SVM支持向量机,一种机器学习算法来判定截取的图块是否是真的“车牌”,本节主要对相关的技术做详细的介绍。
注:SVM相关内容可以详细参考周志华老师的《机器学习》和一篇名为《支持向量机通俗导论(理解SVM的三层境界)》的文章。
一、SVM简介
支持向量机,其英文名为 support vector machine,故一般简称SVM,通俗来讲,它是一种二类分类模型,其基本模型定义为特征空间上的间隔最大的线性分类器,其学习策略便是间隔最大化,最终可转化为一个凸二次规划问题的求解。

如上图所示: 距离超平面最近的几个训练样本点被称之为支持向量(support vector),两个异类支持向量到超平面的距离之和被称之为间隔。对应的SVM的基本型如下:

上述问题本身是一个凸二次规划问题,通过拉格朗日乘子法可得到其对偶问题。

上述两个公式非常重要,简直是核心公式。
得到上面的两个公式,再带回L中把去w和b消掉,得到如下公式:


从对偶问题解出的拉格朗日乘子对应着训练样本(xi,yi)。注意到上式中有不等式约束,因此上述过程需满足KKT条件,即要求

支持向量机有一个重要的性质,训练完成后,大部分的训练样本都不需要保留,最终模型仅与支持向量有关。
接下来就是如何求解这个二次规划问题,可使用通用的二次规划算法来求解,也可以利用问题本身的特性,采用SMO算法来求解。
上面是对SVM的理论做了极其简单的介绍,对支持向量机理论感兴趣的童鞋可以做进一步的研究。
二、车牌判别
opencv中对SVM进行了集成,调用opencv的SVM接口是十分方便的,对于定位的车牌区域,首先获取其车牌特征,这边采用的是LBP算子,具体内容上一节做了详细的介绍。SVM调用的类是opencv 机器学习模块中的SVM类,具体的代码如下所示:
typedef void (*svmCallback)(const cv::Mat& image, cv::Mat& features);
cv::Ptr<ml::SVM> svm_;
svmCallback extractFeature; PlateJudge::PlateJudge() {
svm_ = ml::SVM::load<ml::SVM>(kDefaultSvmPath);
extractFeature = getLBPFeatures;
} void PlateJudge::LoadModel(std::string path) {
if (path != std::string(kDefaultSvmPath)) {
if (!svm_->empty())
svm_->clear(); svm_ = ml::SVM::load<ml::SVM>(path);
}
} int PlateJudge::plateJudge(const Mat &inMat, int &result) {
Mat features;
extractFeature(inMat, features);
float response = svm_->predict(features);
result = (int)response; return ;
}
通过 SVM::load() 函数加载训练好的SVM参数文件,然后调用 predict()函数对当前区域进行判定,是否为车牌。
三、SVM训练
svm训练通过类SvmTrain 来进行,具体的训练函数如下所示:
void SvmTrain::train() {
svm_ = cv::ml::SVM::create();
svm_->setType(cv::ml::SVM::C_SVC);
svm_->setKernel(cv::ml::SVM::RBF);
svm_->setDegree(0.1);
svm_->setGamma(0.1);
svm_->setCoef0(0.1);
svm_->setC();
svm_->setNu(0.1);
svm_->setP(0.1);
svm_->setTermCriteria(cvTermCriteria(CV_TERMCRIT_ITER, , 0.0001));
auto train_data = tdata();
fprintf(stdout, ">> Training SVM model, please wait...\n");
long start = utils::getTimestamp();
svm_->train(train_data);
long end = utils::getTimestamp();
fprintf(stdout, ">> Training done. Time elapse: %ldms\n", end - start);
fprintf(stdout, ">> Saving model file...\n");
svm_->save(svm_xml_);
fprintf(stdout, ">> Your SVM Model was saved to %s\n", svm_xml_);
fprintf(stdout, ">> Testing...\n");
this->test();
}
kernel_type:SVM的内核类型(4种):
CvSVM::POLY : 多项式内核:-- polynomial: (gamma*u'*v + coef0)^degree
CvSVM::RBF : 高斯核-- radial basis function: exp(-gamma*|u-v|^2)
CvSVM::SIGMOID:Sigmoid函数内核-- sigmoid: tanh(gamma*u'*v + coef0)
svm_type:指定SVM的类型(5种):
1、CvSVM::C_SVC : C类支撑向量分类机。 n类分组 (n≥2),容许用异常值处罚因子C进行不完全分类。
2、CvSVM::NU_SVC :
类支撑向量分类机。n类似然不完全分类的分类器。参数为
庖代C(其值在区间【0,1】中,nu越大,决定计划鸿沟越腻滑)。
3、CvSVM::ONE_CLASS : 单分类器,所有的练习数据提取自同一个类里,然后SVM建树了一个分界线以分别该类在特点空间中所占区域和其它类在特点空间中所占区域。
4、CvSVM::EPS_SVR :
类支撑向量回归机。练习集中的特点向量和拟合出来的超平面的间隔须要小于p。异常值处罚因子C被采取。
5、CvSVM::NU_SVR :
类支撑向量回归机。
庖代了 p。
degree:内核函数(POLY)的参数degree。
gamma:内核函数(POLY/ RBF/ SIGMOID)的参数
。
coef0:内核函数(POLY/ SIGMOID)的参数coef0。
Cvalue:SVM类型(C_SVC/ EPS_SVR/ NU_SVR)的参数C。
nu:SVM类型(NU_SVC/ ONE_CLASS/ NU_SVR)的参数
。
p:SVM类型(EPS_SVR)的参数
。
class_weights:C_SVC中的可选权重,赋给指定的类,乘以C今后变成 class_weights*C 。所以这些权重影响不合类此外错误分类处罚项。权重越大,某一类此外误分类数据的处罚项就越大。
term_crit:SVM的迭代练习过程的中断前提,解决项目组受束缚二次最优题目。您可以指定的公差和或最大迭代次数。
对于训练数据 tdata()的获取,如下所示:
cv::Ptr<cv::ml::TrainData> SvmTrain::tdata() {
this->prepare();
cv::Mat samples;
std::vector<int> responses;
for (auto f : train_file_list_) {
auto image = cv::imread(f.file);
if (!image.data) {
fprintf(stdout, ">> Invalid image: %s ignore.\n", f.file.c_str());
continue;
}
cv::Mat feature;
getLBPFeatures(image, feature);
feature = feature.reshape(, );
samples.push_back(feature);
responses.push_back(int(f.label));
}
cv::Mat samples_, responses_;
samples.convertTo(samples_, CV_32FC1);
cv::Mat(responses).copyTo(responses_);
return cv::ml::TrainData::create(samples_, cv::ml::SampleTypes::ROW_SAMPLE,
responses_);
}
对于训练得到的结果,将保存在 svm_xml_文件中。
EasyPR源码剖析(7):车牌判断之SVM的更多相关文章
- EasyPR源码剖析(1):概述
EasyPR(Easy to do Plate Recognition)是本人在opencv学习过程中接触的一个开源的中文车牌识别系统,项目Git地址为https://github.com/liuru ...
- EasyPR源码剖析(6):车牌判断之LBP特征
一.LBP特征 LBP指局部二值模式,英文全称:Local Binary Pattern,是一种用来描述图像局部特征的算子,LBP特征具有灰度不变性和旋转不变性等显著优点. 原始的LBP算子定义在像素 ...
- EasyPR源码剖析(5):车牌定位之偏斜扭转
一.简介 通过颜色定位和Sobel算子定位可以计算出一个个的矩形区域,这些区域都是潜在车牌区域,但是在进行SVM判别是否是车牌之前,还需要进行一定的处理.主要是考虑到以下几个问题: 1.定位区域存在一 ...
- EasyPR源码剖析(3):车牌定位之颜色定位
一.简介 对车牌颜色进行识别,可能大部分人首先想到的是RGB模型, 但是此处RGB模型有一定的局限性,譬如蓝色,其值是255,还需要另外两个分量都为0,不然很有可能你得到的值是白色.黄色更麻烦,它是由 ...
- EasyPR源码剖析(4):车牌定位之Sobel算子定位
一.简介 sobel算子主要是用于获得数字图像的一阶梯度,常见的应用是边缘检测. Ⅰ.水平变化: 将 I 与一个奇数大小的内核进行卷积.比如,当内核大小为3时, 的计算结果为: Ⅱ.垂直变化: 将: ...
- EasyPR源码剖析(2):车牌定位
上一篇主要介绍了车牌识别的整体框架和流程,车牌识别主要划分为了两个过程:即车牌检测和字符识别,而车牌识别的核心环节就是这一节主要介绍的车牌定位,即 Plate Locate.车牌定位主要是将图片中有可 ...
- EasyPR源码剖析(8):字符分割
通过前面的学习,我们已经可以从图像中定位出车牌区域,并且通过SVM模型删除“虚假”车牌,下面我们需要对车牌检测步骤中获取到的车牌图像,进行光学字符识别(OCR),在进行光学字符识别之前,需要对车牌图块 ...
- EasyPR源码剖析(9):字符识别
在上一篇文章的介绍中,我们已经通过相应的字符分割方法,将车牌区域进行分割,得到7个分割字符图块,接下来要做的就是将字符图块放入训练好的神经网络模型,通过模型来预测每个图块所表示的具体字符.神经网络的介 ...
- jQuery之Deferred源码剖析
一.前言 大约在夏季,我们谈过ES6的Promise(详见here),其实在ES6前jQuery早就有了Promise,也就是我们所知道的Deferred对象,宗旨当然也和ES6的Promise一样, ...
随机推荐
- 74.纯 CSS 创作一台 MacBook Pro
原文地址:https://segmentfault.com/a/1190000015568609 HTML code: <div class="macbook"> &l ...
- WebService连接winfrom简单实例
C# 创建.部署和调用WebService的简单示例 webservice 可以用于分布式应用程序之间的交互,和不同程序之间的交互. 具体详细用法可去查询资料.下面开始创建一个简单的webservic ...
- JVM运行、类加载的全过程
类加载机制:JVM把CLASS文件加载到内存,并对数据进行校验.解析和初始化,最终形成JVM可以直接使用的Java文件. 加载:把class文件字节码加载到内存中,并且将这些静态数据转换成方法区中的运 ...
- servlet对象的生命周期
servlet对象默认第一次访问的时候创建,服务器关闭的时候销毁.当servlet对象创建的时候会调用init方法,当对象销毁的时候,会调用destroy方法,每次访问servlet时,都会调用ser ...
- 链表实现python list数据类型
#1.<--用单链表的数据结构实现列表class error(Exception): def __init__(self,msg): super(error,self).__init__(sel ...
- ---Ubuntu 16.04 server 不能关机问题解决
https://serverfault.com/questions/712928/systemctl-commands-timeout-when-ran-as-root Failed to start ...
- mysql日期 获取本月第一天 获取下个月的第一天
--获取当前日期 select curdate(); --获取当月最后一天 select last_day(curdate()); --获取本月第一天 select DATE_ADD(curdate( ...
- lnmp之Nginx配置https加密访问
配置lnmp之Nginx网站支持https加密访问 注: 1. 这里拿购买的(pxsnx.pxjy.com)证书来做样例 证书文件共有三个---> (pxsnxg.pxjy.com_ca.crt ...
- AlphaGo的前世今生(二)AlphaGo: Countdown to AI Revolution
这是本专题的第二节,在这一节我们将以David Silver等人的Natrue论文Mastering the game of Go with deep neural networks and tree ...
- AX2009里调用.NET DLL的效率问题
经常在AX2009里引用.NET的DLL,因为序列化和反序列化,用.NET的定义的实体方便一些,平时数据量不大,也没觉得有什么问题,今天要把几万条数据从数据库中取出来序列化以后,调用第三方系统的接口, ...