OPENCV中使用SVM训练并识别车牌的初步应用
2015-12-09 17:14
579 查看
opencv的CvSVM的实现基于libsvm,libsvm是台湾大学林智仁(Lin Chih-Jen)教授写的一个世界知名的svm库(可能算是目前业界使用率最高的一个库)。svm的perdict方法的输入是待预测数据的特征,也称之为features。在这里,我们输入的特征是图像全部的像素。由于svm要求输入的特征应该是一个向量,而Mat是与图像宽高对应的矩阵,因此在输入前我们需要使用reshape(1,1)方法把矩阵拉伸成向量。
在训练之前要先将待训练的样例分类,一类是车牌图像,一类是非车牌图片,可称为正样例和反样例,分类过程需要很多时间来做。分类好后,就可以把正样例和反样例存入程序中,并做好预处理,具体代码如下:
这里flag参数是传递过来对应训练图片的标识,如果为1则是正样例,如果为0则为反样例,在学习时最好将正例和反例分别放在不到文件夹下,且图像尺寸一致。
其实这里是将图像的所有像素都做为特征进行训练,效果不是很好,实验结果大概只有80%多的正确率,应该找到更好的特征进行训练。
图像读取好后,在主函数中进行调用,代码如下:
因为要获得训练结果的准确识别率不能只用一张一张的图像进行测试,需要用循环来调用test()函数,并记录测试的成功率,而要得知成功率就要有事先标定好的测试集来测试,这一步骤不难,想必大家都能实现。
在训练之前要先将待训练的样例分类,一类是车牌图像,一类是非车牌图片,可称为正样例和反样例,分类过程需要很多时间来做。分类好后,就可以把正样例和反样例存入程序中,并做好预处理,具体代码如下:
<span style="background-color: rgb(240, 240, 240);">//先定义两个全局变量</span>
vector<Mat> trainingImages; vector<int> trainingLabels;
//--------------文件读取-------------------- void file_open(string filedir,int flag) { long lf; vector<string> files; _finddata_t file; string path; if ((lf = _findfirst(path.assign(filedir).append("\\*").c_str(), &file)) == -1) { cout << "File Not Found!" << endl; } else { while (_findnext(lf, &file) == 0) //循环处理文件夹中所有文件,但这里并没有对子文件夹进行检查 { if (strcmp(file.name, "..") == 0) continue; //去掉第一个无用文件名".." files.push_back(path.assign(filedir).append("\\").append(file.name)); //文件路径+文件名保存到files中 //cout << file.name << endl; } } _findclose(lf); //关闭文件查找 cout << "the number of file is :" << files.size() << endl; int size = files.size(); if (0 == size) cout << "No File Found in train HasPlate!" << endl; for (int i = 0; i <files.size(); i++) // { Mat img = imread(files[i].c_str()); //imshow("adad", img); Mat line_i = img.reshape(1, 1); //将待训练图片一维化(如果是提取图片特征进行学习,也需要将特征进行一维化才能用SVM学习) trainingImages.push_back(line_i); //将一维化的img保存 trainingLabels.push_back(flag); //对应的类别标识 } }
这里flag参数是传递过来对应训练图片的标识,如果为1则是正样例,如果为0则为反样例,在学习时最好将正例和反例分别放在不到文件夹下,且图像尺寸一致。
其实这里是将图像的所有像素都做为特征进行训练,效果不是很好,实验结果大概只有80%多的正确率,应该找到更好的特征进行训练。
图像读取好后,在主函数中进行调用,代码如下:
Mat classes;//保存所有正负样例类标 char * filedir = "E:\\data\\plate_detect_svm\\learn\\HasPlate";//正样例的路径 file_open(filedir, 1); //正样例文件读取 filedir = "E:\\data\\plate_detect_svm\\learn\\NoPlate";//负样例路径 file_open(filedir, 0);//负样例文件读取 cout << trainingImages[0].cols << "number"<<trainingImages.size()<< endl; Mat trainingData(trainingImages.size(), trainingImages[0].cols, CV_32FC1);//用来保存所有的正负样例图片或特征 for (int i = 0; i<trainingImages.size(); i++)//将每个一维的训练图像保存至trainingData中 { Mat temp(trainingImages[i]); temp.copyTo(trainingData.row(i));//存至trainingData的第i行上 } //trainingData.convertTo(trainingData, CV_32FC1); Mat(trainingLabels).copyTo(classes); classes.convertTo(classes, CV_32FC1);<span style="font-family: Arial, Helvetica, sans-serif;">//转成SVM要求的格式</span>下面进行SVM参数设置和训练:
//SVM参数设置,这里的参数很多,设置的好坏直接影响学习的结果 CvSVMParams SVM_params; SVM_params.svm_type = CvSVM::C_SVC; SVM_params.kernel_type = CvSVM::LINEAR; //CvSVM::LINEAR; SVM_params.degree = 0; SVM_params.gamma = 1; SVM_params.coef0 = 0; SVM_params.C = 1; SVM_params.nu = 0; SVM_params.p = 0; SVM_params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 1000, 0.01); //开始训练(学习) CvSVM svm(trainingData, classes, Mat(), Mat(), SVM_params); //保存训练模型 FileStorage fsTo("E:/data/svm_plate.xml", FileStorage::WRITE); svm.write(*fsTo, "svm");最后是拿一个图片进行测试:
void test() { CvSVM svm ; svm.clear(); svm.load("E:\\data\\svm_plate.xml"); Mat test_img = imread("E:\\data\\plate_detect_svm\\test\\HasPlate\\A03_AAQ839_3.jpg"); Mat line_test_img = test_img.reshape(1, 1); line_test_img.convertTo(line_test_img, CV_32FC1); int response = (int)svm.predict(line_test_img); if (response == 1) cout << "是车牌" << endl; else cout << "不是车牌" << endl; }
因为要获得训练结果的准确识别率不能只用一张一张的图像进行测试,需要用循环来调用test()函数,并记录测试的成功率,而要得知成功率就要有事先标定好的测试集来测试,这一步骤不难,想必大家都能实现。
相关文章推荐
- python中使用OpenCV进行人脸检测的例子
- opencv 做人脸识别 opencv 人脸匹配分析
- 使用opencv拉伸图像扩大分辨率示例
- 基于C++实现kinect+opencv 获取深度及彩色数据
- OpenCV 2.4.3 C++ 平滑处理分析
- 利用Python和OpenCV库将URL转换为OpenCV格式的方法
- python结合opencv实现人脸检测与跟踪
- 在树莓派2或树莓派B+上安装Python和OpenCV的教程
- opencv-python学习一--人脸检测
- 在Ubuntu上安装OpenCV3.0和Python-openCV的经历
- OpenCV配置,从来没有这么简单!
- ubuntu下opencv和qt的安装配置
- LSI SVM 挑战IBM SVC
- OpenCV学习笔记(二十五)——OpenCV图形界面设计Qt+VS2008
- 分享一些OpenCV实现立体视觉的经验
- 关于OpenCv图像变换与基本图形检测
- "应用程序正常初始化失败"-0xc0150002 解决办法
- OpenCV->HSV色彩空间
- opencv 内存泄露
- OpenCV函数cvFindContours