OpenCV学习(40) 人脸识别(4)

简介: 在人脸识别模式类中,还实现了一种基于LBP直方图的人脸识别方法。LBP图的原理参照:http://www.cnblogs.com/mikewolf2002/p/3438698.html       在代码中,我们只要使用   Ptr model = createLBPHFaceRecognizer(); 就创建了一个基于LBPH的人脸识别类,其它代码和前面两种人脸识别方法一样。

在人脸识别模式类中,还实现了一种基于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

 

相关文章
|
4月前
|
机器学习/深度学习 算法 机器人
|
4月前
|
机器学习/深度学习 人工智能 监控
利用Python和OpenCV实现实时人脸识别系统
【8月更文挑战第31天】本文将引导您了解如何使用Python结合OpenCV库构建一个简易的实时人脸识别系统。通过分步讲解和示例代码,我们将探索如何从摄像头捕获视频流、进行人脸检测以及识别特定个体。本教程旨在为初学者提供一条明晰的学习路径,帮助他们快速入门并实践人脸识别技术。
|
6月前
|
机器学习/深度学习 人工智能 自然语言处理
OpenCV与AI深度学习之常用AI名词解释学习
AGI:Artificial General Intelligence (通用人工智能):是指具备与人类同等或超越人类的智能,能够表现出正常人类所具有的所有智能行为。又被称为强人工智能。
133 2
|
6月前
|
人工智能 计算机视觉 Python
人工智能视觉:基于OpenCV的人脸识别技术的深度解析
人工智能视觉:基于OpenCV的人脸识别技术的深度解析
|
5月前
|
机器学习/深度学习 人工智能 计算机视觉
好的资源-----打卡机+Arm+Qt+OpenCV嵌入式项目-基于人脸识别的考勤系统-----B站神经网络与深度学习,商城
好的资源-----打卡机+Arm+Qt+OpenCV嵌入式项目-基于人脸识别的考勤系统-----B站神经网络与深度学习,商城
|
5月前
|
计算机视觉 Python
opencv 处理图像去噪的几种方法学习
OpenCV 提供了多种图像去噪的方法,以下是一些常见的去噪技术以及相应的 Python 代码示例: 均值滤波:使用像素邻域的灰度均值代替该像素的值。
70 0
|
6月前
|
机器学习/深度学习 监控 算法
使用Python和OpenCV实现简单的人脸识别系统
使用Python和OpenCV实现简单的人脸识别系统
71 0
|
2月前
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
412 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
|
3月前
|
算法 计算机视觉
opencv图像形态学
图像形态学是一种基于数学形态学的图像处理技术,它主要用于分析和修改图像的形状和结构。
51 4
|
3月前
|
存储 计算机视觉
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制
本文介绍了使用OpenCV进行图像读取、显示和存储的基本操作,以及如何绘制直线、圆形、矩形和文本等几何图形的方法。
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制