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一样, ...
随机推荐
- (Python基础)文件操作
对文件操作流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 现有文件如下 命名为7 years Once I was seven years old my momma t ...
- 解决uni-app props 传递数组修改后不能使用问题
1.子组件页面结构 //NoticesMarquee 组件 <view v-for="(item, index) in tempList" :key="index& ...
- 分布式 基本理论 CAP 之 各分布式系统的cap支持情况
分布式系统.理论.协议 非常非常多, 它们多cap 的支持是怎么样的呢? 需要注意的是,分布式系统 为了应付各种 复杂 应用场景,支持各种各样的功能,可能有的提供了选项或某种机制, 某个时刻,支持CP ...
- Toast不消失问题
在实现一个功能的时候,遇到了Toast一直不消失的问题,因此,对Toast进行了一些研究. 先描述问题:有一个activity和一个thread,都有各自的handler.activity启动thre ...
- pgsql 常用命令
1.连接到pgsql数据库 psql -U postgres 2.查看所有数据库 \l 3.连接到数据库test \c test 4.查看数据库所有表以及视图 \d 5.查看数据库所有的表 \dt 6 ...
- 接口--Comparable接口【哈夫曼树】
我们在字符串中见到过CompareTo方法,知道这个方法是用于比较字符串顺序的,根据字典顺序进行排序.Java中很多类也都有CompareTo方法,甚至于排序算法的底层组成也是依赖于比较的,而这个比较 ...
- codeblock 恢复默认字体设置
默认字体为:Courier New 我使用的codeblock版本为:17 .12. 今天我想调整一下codeblock的代码驱的字体,根据设置:settings->Editor->F ...
- Rocket MQ 2 - Namesrv
通过上文中使用可以看到,主要逻辑还是在NamesrvController中包含KVConfigManager负责配置相关的读写,RouteInfoManager负责路由信息的管理; 启动定时任务定时打 ...
- Mybatis级联:关联、集合和鉴别器的使用
Mybatis中级联有关联(association).集合(collection).鉴别器(discriminator)三种.其中,association对应一对一关系.collection对应一对多 ...
- matplotlib绘图基本用法-转自(http://blog.csdn.net/mao19931004/article/details/51915016)
本文转载自http://blog.csdn.net/mao19931004/article/details/51915016 <!DOCTYPE html PUBLIC "-//W3C ...