OpenCV学习(40) 人脸识别(4)
在人脸识别模式类中,还实现了一种基于LBP直方图的人脸识别方法。LBP图的原理参照:http://www.cnblogs.com/mikewolf2002/p/3438698.html
在代码中,我们只要使用 Ptr<FaceRecognizer> model = createLBPHFaceRecognizer(); 就创建了一个基于LBPH的人脸识别类,其它代码和前面两种人脸识别方法一样。
在train函数中,会计算每个样本的LBP图像,并求出该图像的二维直方图,把直方图保存在_histograms中,以便在predict函数调用这些直方图进行匹配。
for(size_t sampleIdx = 0; sampleIdx < src.size(); sampleIdx++)
{
// 计算LBP图
Mat lbp_image = elbp(src[sampleIdx], _radius, _neighbors);
// 得到直方图
Mat p = spatial_histogram(
lbp_image, /* lbp_image */
static_cast<int>(std::pow(2.0, static_cast<double>(_neighbors))), //可能的模式数
_grid_x, /* grid size x */
_grid_y, /* grid size y */
true);
// 把直方图加到匹配模版中
_histograms.push_back(p);
}
在预测函数中,会先求出输入图像的LBPH图,然后和保存的样本LBPH进行比较,距离最今即为匹配的人脸。
Mat lbp_image = elbp(src, _radius, _neighbors);
Mat query = spatial_histogram(
lbp_image, /* lbp_image */
static_cast<int>(std::pow(2.0, static_cast<double>(_neighbors))), /* number of possible patterns */
_grid_x, /* grid size x */
_grid_y, /* grid size y */
true /* normed histograms */);
// 查找最近的匹配者
minDist = DBL_MAX;
minClass = -1;
for(size_t sampleIdx = 0; sampleIdx < _histograms.size(); sampleIdx++)
{
double dist = compareHist(_histograms[sampleIdx], query, CV_COMP_CHISQR);
if((dist < minDist) && (dist < _threshold))
{
minDist = dist;
minClass = _labels.at<int>((int) sampleIdx);
}
}
代码:
#include "opencv2/core/core.hpp"
#include "opencv2/contrib/contrib.hpp"
#include "opencv2/highgui/highgui.hpp" #include <iostream>
#include <fstream>
#include <sstream> using namespace cv;
using namespace std; static void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, char separator = ';') {
std::ifstream file(filename.c_str(), ifstream::in);
if (!file) {
string error_message = "No valid input file was given, please check the given filename.";
CV_Error(CV_StsBadArg, error_message);
}
string line, path, classlabel;
while (getline(file, line)) {
stringstream liness(line);
getline(liness, path, separator);
getline(liness, classlabel);
if(!path.empty() && !classlabel.empty()) {
images.push_back(imread(path, 0));
labels.push_back(atoi(classlabel.c_str()));
}
}
} int main(int argc, const char *argv[])
{ // Get the path to your CSV.
string fn_csv = string("facerec_at_t.txt");
// These vectors hold the images and corresponding labels.
vector<Mat> images;
vector<int> labels;
// Read in the data. This can fail if no valid
// input filename is given.
try {
read_csv(fn_csv, images, labels);
} catch (cv::Exception& e) {
cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl;
// nothing more we can do
exit(1);
}
// Quit if there are not enough images for this demo.
if(images.size() <= 1) {
string error_message = "This demo needs at least 2 images to work. Please add more images to your data set!";
CV_Error(CV_StsError, error_message);
}
// Get the height from the first image. We'll need this
// later in code to reshape the images to their original
// size:
int height = images[0].rows;
// The following lines simply get the last images from
// your dataset and remove it from the vector. This is
// done, so that the training data (which we learn the
// cv::FaceRecognizer on) and the test data we test
// the model with, do not overlap.
Mat testSample = images[images.size() - 1];
int testLabel = labels[labels.size() - 1];
images.pop_back();
labels.pop_back();
// The following lines create an LBPH model for
// face recognition and train it with the images and
// labels read from the given CSV file.
//
// The LBPHFaceRecognizer uses Extended Local Binary Patterns
// (it's probably configurable with other operators at a later
// point), and has the following default values
//
// radius = 1
// neighbors = 8
// grid_x = 8
// grid_y = 8
//
// So if you want a LBPH FaceRecognizer using a radius of
// 2 and 16 neighbors, call the factory method with:
//
// cv::createLBPHFaceRecognizer(2, 16);
//
// And if you want a threshold (e.g. 123.0) call it with its default values:
//
// cv::createLBPHFaceRecognizer(1,8,8,8,123.0)
//
Ptr<FaceRecognizer> model = createLBPHFaceRecognizer();
model->train(images, labels);
// The following line predicts the label of a given
// test image:
int predictedLabel = model->predict(testSample);
//
// To get the confidence of a prediction call the model with:
//
// int predictedLabel = -1;
// double confidence = 0.0;
// model->predict(testSample, predictedLabel, confidence);
//
string result_message = format("Predicted class = %d / Actual class = %d.", predictedLabel, testLabel);
cout << result_message << endl;
// Sometimes you'll need to get/set internal model data,
// which isn't exposed by the public cv::FaceRecognizer.
// Since each cv::FaceRecognizer is derived from a
// cv::Algorithm, you can query the data.
//
// First we'll use it to set the threshold of the FaceRecognizer
// to 0.0 without retraining the model. This can be useful if
// you are evaluating the model:
//
model->set("threshold", 0.0);
// Now the threshold of this model is set to 0.0. A prediction
// now returns -1, as it's impossible to have a distance below
// it
predictedLabel = model->predict(testSample);
cout << "Predicted class = " << predictedLabel << endl;
// Show some informations about the model, as there's no cool
// Model data to display as in Eigenfaces/Fisherfaces.
// Due to efficiency reasons the LBP images are not stored
// within the model:
cout << "Model Information:" << endl;
string model_info = format("\tLBPH(radius=%i, neighbors=%i, grid_x=%i, grid_y=%i, threshold=%.2f)",
model->getInt("radius"),
model->getInt("neighbors"),
model->getInt("grid_x"),
model->getInt("grid_y"),
model->getDouble("threshold"));
cout << model_info << endl;
// We could get the histograms for example:
vector<Mat> histograms = model->getMatVector("histograms");
// But should I really visualize it? Probably the length is interesting:
cout << "Size of the histograms: " << histograms[0].total() << endl;
return 0;
}
程序代码:工程FirstOpenCV35
OpenCV学习(40) 人脸识别(4)的更多相关文章
- OpenCV学习(38) 人脸识别(3)
前面我们学习了基于特征脸的人脸识别,现在我们学习一下基于Fisher脸的人脸识别,Fisher人脸识别基于LDA(线性判别算法)算法,算法的详细介绍可以参考下面两篇教程内容: ...
- OpenCV学习(37) 人脸识别(2)
在前面一篇教程中,我们学习了OpenCV中基于特征脸的人脸识别的代码实现,我们通过代码 Ptr<FaceRecognizer> model = createEigenFaceR ...
- OpenCV学习(36) 人脸识别(1)
本文主要参考OpenCV人脸识别教程:http://docs.opencv.org/modules/contrib/doc/facerec/facerec_tutorial.html 1.OpenCV ...
- 【从零学习openCV】IOS7人脸识别实战
前言 接着上篇<IOS7下的人脸检測>,我们顺藤摸瓜的学习怎样在IOS7下用openCV的进行人脸识别,实际上非常easy,因为人脸检測部分已经完毕,剩下的无非调用openCV的方法对採集 ...
- 基于深度学习的人脸识别系统(Caffe+OpenCV+Dlib)【一】如何配置caffe属性表
前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...
- 基于深度学习的人脸识别系统(Caffe+OpenCV+Dlib)【三】VGG网络进行特征提取
前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...
- 基于深度学习的人脸识别系统(Caffe+OpenCV+Dlib)【二】人脸预处理
前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...
- 基于深度学习的人脸识别系统系列(Caffe+OpenCV+Dlib)——【四】使用CUBLAS加速计算人脸向量的余弦距离
前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...
- 基于Opencv快速实现人脸识别(完整版)
无耻收藏网页链接: 基于OpenCV快速实现人脸识别:https://blog.csdn.net/beyond9305/article/details/92844258 基于Opencv快速实现人脸识 ...
随机推荐
- C#中 EF(EntityFramework) 性能优化
现在工作中很少使用原生的sql了,大多数的时候都在使用EF.刚开始的时候,只是在注重功能的实现,最近一段时间在做服务端接口开发.开发的时候也是像之前一样,键盘噼里啪啦的一顿敲,接口秒秒钟上线,但是到联 ...
- Python爬虫个人记录(二) 获取fishc 课件下载链接
参考: Python爬虫个人记录(一)豆瓣250 (2017.9.6更新,通过cookie模拟登陆方法,已成功实现下载文件功能!!) 一.目的分析 获取http://bbs.fishc.com/for ...
- R语言实战(六)重抽样与自助法
本文对应<R语言实战>第12章:重抽样与自助法 之前学习的基本统计分析.回归分析.方差分析,是假定观测数据抽样自正态分布或者其他性质较好的理论分布,进而进行的假设检验和总体参数的置信区间估 ...
- eclipse使用小技巧
1.eclipse中SVN无版本信息显示,window-preference-general-appeerance-label decoration-svn勾上,显示有关项目中受 SVN 控制的资源的 ...
- JavaScript基础-DAY2
JavaScript对象 在JavaScript中除了null和undefined以外其他的数据类型都被定义成了对象,也可以用创建对象的方法定义变量,String.Math.Array.Date.Re ...
- 深入理解RESTful Web Services
RESTful的软件架构已经多火不用多说,和MVC架构一样,很多网站服务(Web Services)都遵循RESTful设计模式,那么到底什么是RESTful Web Services呢?设计一个RE ...
- HDU 5694 BD String 迭代
BD String 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5694 Description Problem Description 众所周知, ...
- git 的补丁使用方法
1.生成补丁 format-patch可以基于分支进行打包,也可以基于上几次更新内容打包. 基于上几次内容打包 git format-patch HEAD^ 有几个^就会打几个patch,从最近一次 ...
- http://qurtyy.blog.163.com/blog/static/5744368120130221419244/
我们先来看它的思路:把控制不透明度和控向上移动的动画分别存储在两个队列中,控制向上移动的队列按默认情况进行(在2000毫秒内完成),而不透明度的控制在1000毫秒内执行,但这个队列要晚于默认队列100 ...
- clip-path 教程:使用 CSS 中的 clip-path 轻松实现多边形
作为一个前端开发,一个主要的工作就是来实现设计师设计的UI界面.而在UI界面中,各种各样的形状元素应用则是随处可见,比如三角形: 以前碰到这种形状的时候,会使用各种黑科技的技巧,比如使用CSS中的bo ...