基于SVM和神经网络的车牌识别(二)
本系列文章参考自《深入理解OpenCV实用计算机视觉项目解析》仅作学习用途
基于SVM的图像分类
在上一篇中,我们最后得到的图像,有一定可能不是车牌,所以需要加入一个分类的程序,把车牌和非车牌分开。在书中,使用SVM实现分类的功能。
书上没有给出创建训练和测试图像数据的步骤,但是给了一个xml文件(见下图),文件中是用于训练和测试的文本数据,下面直接使用这个xml文件,训练我们的分类器。
本篇使用的测试图片是:
#include <iostream>
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <ml.hpp>
using namespace std;
using namespace cv;
using namespace ml;
/* 基于SVM的图像分类 */
bool classification(Mat image_crop) {
// Step0. 处理输入图像,对大小和type都有具体的规定
// rows = 33, cols = 144, type = 5 (CV_32FC1)
Mat src;
src.create(33, 144, CV_32FC1);
resize(image_crop, src, src.size(), 0, 0, INTER_CUBIC);
src.convertTo(src, CV_32FC1);
src = src.reshape(1, 1);
// Step1. 设置训练数据
// 这里基于OpenCV310,写法可能与OpenCV249等不同
FileStorage fs;
fs.open("SVM.xml", FileStorage::READ);
Mat trainingDataMat;
Mat classesMat;
fs["TrainingData"] >> trainingDataMat;
fs["classes"] >> classesMat;
Ptr<TrainData> trainingData = TrainData::create(trainingDataMat, ROW_SAMPLE, classesMat);
// Step2. 创建分类器,并设置参数
SVM::ParamTypes params;
SVM::KernelTypes kernel_type = SVM::LINEAR;
Ptr<SVM> svm = SVM::create();
svm->setKernel(kernel_type);
// Step3. 训练分类器
svm->trainAuto(trainingData);
// Step4. 预测
// 1表示是车牌,0表示非车牌
int response = svm->predict(src);
return response;
}
int main() {
Mat src = imread("2715DTZ.jpg", 0);
bool flag = classification(src);
cout << "flag = " << flag << endl;
waitKey();
return 0;
}
程序的运行结果为:
感觉这个分类器有时候并不准确,对于下面这张图,分类的结果就是非车牌
(T_T)。由于没有自己做数据,猜测训练数据中的车牌都比较方方正正,角度也近似水平,如果能增大训练样本,应该会更准确一些。
参考:
系列文章
OpenCV自学笔记17. 基于SVM和神经网络的车牌识别(一)
OpenCV自学笔记18. 基于SVM和神经网络的车牌识别(二)
OpenCV自学笔记19. 基于SVM和神经网络的车牌识别(三)
OpenCV自学笔记20. 基于SVM和神经网络的车牌识别(四)