opencv SVM多分类 人脸识别
2017-10-14 16:54
1361 查看
上一篇介绍了OPENCV中SVM的简单使用,以及自带的一个二分类问题。
例子中的标签是程序手动写的,输入也是手动加的二维坐标点。
对于复杂问题就必须使用数据集中的图片进行训练,标签使用TXT文件或程序设置好,下面以 IMM Face Database 中的人脸数据作为示例,
实现人脸的HOG特征提取及SVM识别人脸。
数据集参考我的http://www.cnblogs.com/chenzhefan/p/7624811.html;只选取其中5类人,每类5副图片作为训练。
提取人脸HOG特征的维数为1764,具体见代码设置。
上述函数主要完成提取训练图片的HOG特征,并用SVM训练模型,保存为XML文件方便快速使用。
训练结果如图:
训练完成后即可以使用测试图片进行图片识别了:
预测结果:
小样本图片SVM的识别结果还是很不错的。本文的测试图片较少,也不能说明模型到底有多好,但基于opencv SVM的识别分类流程基本是这样了。
有问题欢迎讨论~
例子中的标签是程序手动写的,输入也是手动加的二维坐标点。
对于复杂问题就必须使用数据集中的图片进行训练,标签使用TXT文件或程序设置好,下面以 IMM Face Database 中的人脸数据作为示例,
实现人脸的HOG特征提取及SVM识别人脸。
数据集参考我的http://www.cnblogs.com/chenzhefan/p/7624811.html;只选取其中5类人,每类5副图片作为训练。
提取人脸HOG特征的维数为1764,具体见代码设置。
void HogSVM() { int ImgWidht = 64; int ImgHeight = 64; vector<string> img_path; vector<int> img_catg; int nLine = 0; string buf; ifstream svm_data("E:\\vswork\\car3\\train\\train.txt"); unsigned long n; for (int catg = 0; catg < 5; catg++) { for (int num = 0; num < 5; num++) { if (getline(svm_data, buf)) { img_catg.push_back(catg);//图像类别 img_path.push_back(buf);//图像路径 nLine++; } } } svm_data.close();//关闭文件 Mat data_mat, res_mat; int nImgNum = nLine; //读入样本数量 //样本矩阵,nImgNum:行数代表样本的数量,每一行就是由一张图片计算得到HOG的特征向量, data_mat = Mat::zeros(nImgNum, 1764, CV_32FC1); res_mat = Mat::zeros(nImgNum, 1, CV_32FC1); Mat src; Mat trainImg = Mat::zeros(ImgHeight, ImgWidht, CV_8UC3);//需要分析的图片 for (string::size_type i = 0; i != img_path.size(); i++) { src = imread(img_path[i].c_str(), 1); cout << " processing " << img_path[i].c_str() << endl; resize(src, trainImg, cv::Size(ImgWidht, ImgHeight), 0, 0, INTER_CUBIC); HOGDescriptor *hog = new HOGDescriptor(cvSize(ImgWidht, ImgHeight), cvSize(16, 16), cvSize(8, 8), cvSize(8, 8), 9); //构造HOG,具体意思见参考文章1,2 vector<float>descriptors;//结果数组 hog->compute(trainImg, descriptors, Size(1, 1), Size(0, 0)); //调用计算函数开始计算 if (i == 0) { data_mat = Mat::zeros(nImgNum, descriptors.size(), CV_32FC1); //根据输入图片大小进行分配空间 } cout << "HOG dims: " << descriptors.size() << endl; n = 0; for (vector<float>::iterator iter = descriptors.begin(); iter != descriptors.end(); iter++) { data_mat.at<float>(i, n) = *iter; n++; } res_mat.at<float>(i, 0) = img_catg[i]; cout << " end processing " << img_path[i].c_str() << " " << img_catg[i] << endl; } CvSVM svm; CvSVMParams param; CvTermCriteria criteria; criteria = cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON); param = CvSVMParams(CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria); svm.train(data_mat, res_mat, Mat(), Mat(), param); svm.save("SVM_DATA.xml"); return; }
上述函数主要完成提取训练图片的HOG特征,并用SVM训练模型,保存为XML文件方便快速使用。
训练结果如图:
训练完成后即可以使用测试图片进行图片识别了:
void HogSVMPre() { //检测样本 vector<string> img_tst_path; string buf; unsigned long n; int ImgWidht = 64; int ImgHeight = 64; Mat TestImg = Mat::zeros(ImgHeight, ImgWidht, CV_8UC3); ifstream img_tst("E:\\vswork\\car3\\val\\val.txt"); while (img_tst) { if (getline(img_tst, buf)) { img_tst_path.push_back(buf); } } img_tst.close(); CvSVM svm; svm.load("SVM_DATA.xml"); Mat test; char line[512]; ofstream predict_txt("SVM_PREDICT.txt"); for (string::size_type j = 0; j != img_tst_path.size(); j++) { test = imread(img_tst_path[j].c_str(), 1);//读入图像 resize(test, TestImg, cv::Size(ImgWidht, ImgHeight), 0, 0, INTER_CUBIC);//要搞成同样的大小才可以检测到 HOGDescriptor *hog = new HOGDescriptor(cvSize(ImgWidht, ImgHeight), cvSize(16, 16), cvSize(8, 8), cvSize(8, 8), 9); //窗口大小,块大小,块滑动增量,cell的大小,bins的个数 vector<float>descriptors;//结果数组 hog->compute(TestImg, descriptors, Size(1, 1), Size(0, 0)); //调用计算函数开始计算 cout << "The Detection Result:" << endl; cout << "HOG dims: " << descriptors.size() << endl; Mat SVMtrainMat = Mat::zeros(1, descriptors.size(), CV_32FC1); n = 0; for (vector<float>::iterator iter = descriptors.begin(); iter != descriptors.end(); iter++) { SVMtrainMat.at<float>(0, n) = *iter; n++; } int ret = svm.predict(SVMtrainMat); std::sprintf(line, "%s %d\r\n", img_tst_path[j].c_str(), ret); printf("%s %d\r\n", img_tst_path[j].c_str(), ret);//输出预测的结果,ret的值就代表类别 //getchar(); predict_txt << line; } predict_txt.close(); system("PAUSE"); return; }
预测结果:
小样本图片SVM的识别结果还是很不错的。本文的测试图片较少,也不能说明模型到底有多好,但基于opencv SVM的识别分类流程基本是这样了。
有问题欢迎讨论~
相关文章推荐
- keras系列︱人脸表情分类与识别:opencv人脸检测+Keras情绪分类(四)
- opencv knn,svm,ann,人脸识别类的使用总结
- 数据挖掘—LDA,PCA特征提取降维与SVM多分类在人脸识别中的应用-数据集ORL
- 利用opencv的hog+svm实现细胞识别分类器
- 基于 OpenCV 的 LBP + SVM 人脸识别
- keras系列︱人脸表情分类与识别:opencv人脸检测+Keras情绪分类(四)
- opencv3/C++ 机器学习-SVM应用实例:药品(胶囊)识别与分类
- keras系列︱人脸表情分类与识别:opencv人脸检测+Keras情绪分类(四)
- 使用OpenCV+PCA+KNN/SVM进行人脸检测和识别-Python
- 【OpenCV】特征人脸 训练、识别、重构、存取
- 基于opencv2.0的haar算法以人脸识别为例的训练分类器xml的方法
- TensorFlow实现人脸识别(2)------利用opencv在视频中识别人脸并且保存
- opencv--读取摄像头识别人脸并跟踪
- Opencv 人脸识别
- 人脸识别keras+opencv(三):遇到的问题
- opencv 中的人脸识别源程序 基于haar特征的adaboost算法
- opencv 人脸识别 java版------2
- Solaris下人脸识别程序(OpenCV)
- opencv人脸识别,瞳孔检测
- [置顶] OpenCV — 人脸识别