opencv 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 = ;
int ImgHeight = ;
vector<string> img_path;
vector<int> img_catg;
int nLine = ;
string buf;
ifstream svm_data("E:\\vswork\\car3\\train\\train.txt");
unsigned long n; for (int catg = ; catg < ; catg++)
{
for (int num = ; num < ; 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, , CV_32FC1);
res_mat = Mat::zeros(nImgNum, , CV_32FC1); Mat src;
Mat trainImg = Mat::zeros(ImgHeight, ImgWidht, CV_8UC3);//需要分析的图片 for (string::size_type i = ; i != img_path.size(); i++)
{
src = imread(img_path[i].c_str(), ); cout << " processing " << img_path[i].c_str() << endl; resize(src, trainImg, cv::Size(ImgWidht, ImgHeight), , , INTER_CUBIC);
HOGDescriptor *hog = new HOGDescriptor(cvSize(ImgWidht, ImgHeight), cvSize(, ), cvSize(, ), cvSize(, ), ); //构造HOG,具体意思见参考文章1,2
vector<float>descriptors;//结果数组
hog->compute(trainImg, descriptors, Size(, ), Size(, )); //调用计算函数开始计算
if (i == )
{
data_mat = Mat::zeros(nImgNum, descriptors.size(), CV_32FC1); //根据输入图片大小进行分配空间
}
cout << "HOG dims: " << descriptors.size() << endl;
n = ;
for (vector<float>::iterator iter = descriptors.begin(); iter != descriptors.end(); iter++)
{
data_mat.at<float>(i, n) = *iter;
n++;
}
res_mat.at<float>(i, ) = 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, , 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 = ;
int ImgHeight = ;
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[];
ofstream predict_txt("SVM_PREDICT.txt");
for (string::size_type j = ; j != img_tst_path.size(); j++)
{
test = imread(img_tst_path[j].c_str(), );//读入图像
resize(test, TestImg, cv::Size(ImgWidht, ImgHeight), , , INTER_CUBIC);//要搞成同样的大小才可以检测到
HOGDescriptor *hog = new HOGDescriptor(cvSize(ImgWidht, ImgHeight), cvSize(, ), cvSize(, ), cvSize(, ), ); //窗口大小,块大小,块滑动增量,cell的大小,bins的个数
vector<float>descriptors;//结果数组
hog->compute(TestImg, descriptors, Size(, ), Size(, )); //调用计算函数开始计算
cout << "The Detection Result:" << endl;
cout << "HOG dims: " << descriptors.size() << endl;
Mat SVMtrainMat = Mat::zeros(, descriptors.size(), CV_32FC1);
n = ;
for (vector<float>::iterator iter = descriptors.begin(); iter != descriptors.end(); iter++)
{
SVMtrainMat.at<float>(, 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的识别分类流程基本是这样了。
有问题欢迎讨论~
opencv SVM多分类 人脸识别的更多相关文章
- OpenCV学习 物体检测 人脸识别 填充颜色
介绍 OpenCV是开源计算机视觉和机器学习库.包含成千上万优化过的算法.项目地址:http://opencv.org/about.html.官方文档:http://docs.opencv.org/m ...
- python与opencv的结合之人脸识别值
首先还是要感谢http://www.jb51.net/article/67392.htm这位大神的无私奉献,开源的代码,让我省去了很多事,但是就光系统环境的配置就花去了我将近一个星期的时间,真是不容易 ...
- 使用OpenCV和Python进行人脸识别
介绍 人脸识别是什么?或识别是什么?当你看到一个苹果时,你的大脑会立刻告诉你这是一个苹果.在这个过程中,你的大脑告诉你这是一个苹果水果,用简单的语言来说就是识别.那么什么是人脸识别呢?我肯定你猜对了. ...
- 利用face_recognition,dlib与OpenCV调用摄像头进行人脸识别
用已经搭建好 face_recognition,dlib 环境来进行人脸识别 未搭建好环境请参考:https://www.cnblogs.com/guihua-pingting/p/12201077. ...
- opencv+python3.4的人脸识别----2017-7-19
opencv3.1 + python3.4 第一回合(抄代码,可实现):人脸识别涉及一个级联表,目前能力还无法理解. 流程:1.读取图像---2.转换为灰度图---3.创建级联表---4.对灰度图 ...
- java+opencv+intellij idea实现人脸识别
首先当然是需要安装opencv了,我用的是opencv2.4.13.下载完之后就可以直接安装了,安装过程也很简单,直接下一步下一步就好,我就不上图了. 接下来在opencv下找到jar包,比如我直接安 ...
- ios OpenCv的配置和人脸识别技术
作为一个好奇心非常重的人,面对未知的世界都想去一探到底. 于是做了个人脸识别的demo. 眼下国内的关于opencv技术文章非常少.都是互相抄袭.关键是抄个一小部分还不全.时间又是非常久之前的了,和如 ...
- Opencv级联分类器实现人脸识别
在本章中,我们将学习如何使用OpenCV使用系统相机捕获帧.org.opencv.videoio包的VideoCapture类包含使用相机捕获视频的类和方法.让我们一步一步学习如何捕捉帧 - 第1步: ...
- OpenCV+python 人脸识别
首先给大家推荐一本书:机器学习算法原理与编程实践 本文内容全部转载于书中,相当于一个读书笔记了吧 绪论 1992年麻省理工学院通过实验对比了基于结构特征的方法与基于模版匹配的方法,发现模版匹配的方法要 ...
随机推荐
- 从0在windows上一次性上传本地整个项目(包含所有文件/文件夹)到 Github
1.注册并登陆Github. 2.登陆进去之后的页面,点击这个“库”,这表示你在Github上上的代码仓库,我这里已经创建过一个了,所以数量是1 3.在仓库选项卡中,点击“新建”按钮添加一个项目. 4 ...
- wireshark系列之wireshark过滤器
一:过滤器 使用wireshark工具抓包,如果使用默认配置,会得到大量的数据,所以我们就很难找到我们要分析的封包数据.所以使用wireshark过滤器就显得尤为重要. wireshark过滤器分为两 ...
- Antenna Placement POJ - 3020 (最小边集覆盖)
Antenna Placement Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10699 Accepted: 526 ...
- Racket里的方括号
Racket里的方括号 Racket编程指南 https://blog.csdn.net/chinazhangyong/article/category/7386082 来自于QQ群racket!( ...
- 部署harbor1.2.0开启ldap验证
就harbor本身部署来说是非常简单的,之前写过详细步骤,这里不再重复. 这里主要是总结一下部署当中遇到的问题,以及如何开启ldap验证. harbor默认是通过http通信的,当然也支持https, ...
- emoji表情存储到数据库的方法
方案1:修改数据库编码 为什么我们设置表的的字符类型为utf8却不能存放emoji呢?原来utf8可能是2或3或4个字节,而mysql的utf8是3个字节,存放一个emoji是需要4个字节的,自然不够 ...
- np.linespace使用方法
np.linespace用法 觉得有用的话,欢迎一起讨论相互学习~Follow Me 生成指定范围内指定个数的一维数组 def linspace(start, stop, num=50, endpoi ...
- 分布式锁--Redis小试牛刀
参考文章: Redis分布式锁的正确实现方式 分布式锁看这篇就够了 在这两篇文章的指引下亲测 Redis分布式锁 引言 分布式系统一定会存在CAP权衡问题,所以才会出现分布式锁 什么是CAP理论? 为 ...
- Tomcat get 中文乱码
乱码问题 原因: tomcat默认的在url传输时是用iso8859-1编码. 解决方案一: 在使用get传输参数时,将参数中的中文转换成url格式,也就是使用urlEncode和urlDecode来 ...
- bzoj千题计划206:bzoj1076: [SCOI2008]奖励关
http://www.lydsy.com/JudgeOnline/problem.php?id=1076 很容易想到方程 dp[i][j]表示抛出了i个宝物,已选宝物状态为j的期望最大得分 初始化dp ...