基于opencv2的人脸识别系统(一)

时间:2021-04-19 08:45:12

    之前,曾写过一个较为完整的人脸识别小系统。开发环境为opencv2.4.9和VS2012,并加入了一个新模块cvui.h,用此模块为人脸识别系统写了一个简单界面。

     此界面用到的元素比较简单,包含按钮、文本框、图片及文字。界面如下:

                    基于opencv2的人脸识别系统(一)

                    基于opencv2的人脸识别系统(一)

本文章写作框架如下:

1. 人脸识别流程

                        基于opencv2的人脸识别系统(一)

2.各部分功能

3.各部分中遇到的细节问题

     例如:

       CascadeClassifier cascade;//建立级联分类器

cascade.load("haarcascade_frontalface_alt2.xml"); // 加载训练好的 人脸检测器(.xml)

        cascade.detectMultiScale(frameGray,faces,1.2, 2,0 |  CV_HAAR_FIND_BIGGEST_OBJECT );

        haarcascade_frontalface_alt2.xml到底是什么东西?

4.本系统的缺陷,是否可提升

  (1)  人脸采集问题:人脸旋转-》矫正

(2)训练模型问题:更换更好的模型来训练-》深度学习

(3)样本格式问题:直接利用彩色图像会不会更好

(4)训练样本问题:人脸数据库数量不足,以及ORL是西方面孔,与我们东方面孔的差异。-》采集更多东方人脸,进行训练

(5)人脸数组:现在是只识别一个人,能否识别多个,可以

(6)自己训练人脸检测器haar_cascade

5.所涉及的算法,要讲清楚原理

6.具体代码请戳:http://blog.csdn.net/u012679707/article/details/79520299 基于opencv2的人脸识别系统(二)具体代码



各模块讲解

第一部分:主函数

main.c

系统主函数,包含参数初始化、ui界面的设置以及整体流程控制。


第二部分:人脸采集

capture.cpp

人脸采集模块,功能是从摄像头画面中检测出人脸,并将人脸图像(矩形)截取下来,保存到训练文件中。其中人脸检测的详细过程是,

第一步,建立级联分类器

CascadeClassifier cascade;//建立级联分类器

第二步,加载Haar级联分类器模型.xml

cascade.load("haarcascade_frontalface_alt2.xml");	// 加载训练好的 人脸检测器(.xml)

第三步,用加载好的级联分类器进行人脸检测,返回检测到的人脸数组faces

cascade.detectMultiScale(frameGray,faces,1.2, 2,0 |  CV_HAAR_FIND_BIGGEST_OBJECT );

流程图如下:

                    基于opencv2的人脸识别系统(一)


这一模块中,有一个问题,haar是什么?haar.xml为什么可以做人脸检测模型?如何检测出人脸的?

首先,haar特征是一种特征提取的方法。其实,特征提取方法有很多种,比如说Haar特征,edgelet特征,shapelet特征,HOG特征,HOF特征,小波特征,边缘模板等等。

摘录自:http://blog.csdn.net/yang6464158/article/details/25103703(特征提取之——Haar特征

Haar分类器 = Haar-like特征 + 积分图方法 + AdaBoost +级联

Haar分类器算法的要点如下:

① 使用Haar-like特征做检测。

② 使用积分图(Integral Image)对Haar-like特征求值进行加速。

③ 使用AdaBoost算法训练区分人脸和非人脸的强分类器。

④ 使用筛选式级联把强分类器级联到一起,提高准确率。


大神贴在此,非常详细的算法过程讲解。

http://blog.csdn.net/beizhengren/article/details/77095724  (haar特征介绍与分析)

http://blog.csdn.net/beizhengren/article/details/77095759  (积分图,快速计算图像中任意位置的haar特征值)

http://blog.csdn.net/beizhengren/article/details/77095841  (强弱级联分类器与xml文件参数含义)

http://blog.csdn.net/beizhengren/article/details/77095883   (利用并查集合并检测窗口)

http://blog.csdn.net/beizhengren/article/details/77095969  (利用opencv_traincascade.exe训练自己的分类器)

http://blog.csdn.net/beizhengren/article/details/77095988     (具体训练过程分析)

opencv 用opencv_traincascade.exe训练haar分类器


第三部分:模型训练 train.cpp

流程图如下:

                                  基于opencv2的人脸识别系统(一)

1.前期准备工作,将所有的人脸样本和类别标签生成一个.csv文件。

        生成csv文件方法:http://blog.csdn.net/u012679707/article/details/79519143    (gogo小Sa)

  2.训练时可直接读取csv文件,实现样本和类别标签的获取。

       读取csv文档方法: http://blog.csdn.net/u012679707/article/details/78711365 (gogo小Sa)

3.创建特征脸模型,选择20个主成分   (faceRecognizer 为cv2中的contrib模块)

Ptr<FaceRecognizer> model=createEigenFaceRecognizer(20); // 创建特征脸模型 20张主成分脸

4.通过样本和类别标签进行训练,最终得到训练好的主成分脸模型。

model->train(images,labels); //训练人脸模型,通过images和labels来训练人脸模型

5.将模型保存为.xml文件

model->save("MyFacePcaModel.xml"); //将训练模型保存到MyFacePcaModel.xml

注意:contrib模块中的人脸识别模型有三种,PCA、fisher、LBP。本系统选择的是主成分脸模型(PCA)


最终生成的MyFacePcaModel.xml文件内容如下图所示,其中

<num_components>20</num_components>   20是主特征脸的个数
<rows>1</rows><cols>10304</cols>       1*10304 这表示每个特征脸的大小,一行表示一张脸的数据,维度为10304(92*112)


基于opencv2的人脸识别系统(一)

                       图3.1 MyFacePcaModel.xml

其中,faceRecognizer源码解析如下:详细解析可参见大神贴                                                                                                                                  http://www.cnblogs.com/guoming0000/archive/2012/09/27/2706019.html

 class CV_EXPORTS_W FaceRecognizer : public Algorithm    {    public:        //! virtual destructor        virtual ~FaceRecognizer() {}        // Trains a FaceRecognizer.        CV_WRAP virtual void train(InputArrayOfArrays src, InputArray labels) = 0;        // Updates a FaceRecognizer.        CV_WRAP void update(InputArrayOfArrays src, InputArray labels);        // Gets a prediction from a FaceRecognizer.        virtual int predict(InputArray src) const = 0;        // Predicts the label and confidence for a given sample.        CV_WRAP virtual void predict(InputArray src, CV_OUT int &label, CV_OUT double &confidence) const = 0;        // Serializes this object to a given filename.        CV_WRAP virtual void save(const string& filename) const;        // Deserializes this object from a given filename.        CV_WRAP virtual void load(const string& filename);        // Serializes this object to a given cv::FileStorage.        virtual void save(FileStorage& fs) const = 0;        // Deserializes this object from a given cv::FileStorage.        virtual void load(const FileStorage& fs) = 0;    };    CV_EXPORTS_W Ptr<FaceRecognizer> createEigenFaceRecognizer(int num_components = 0, double threshold = DBL_MAX);    CV_EXPORTS_W Ptr<FaceRecognizer> createFisherFaceRecognizer(int num_components = 0, double threshold = DBL_MAX);    CV_EXPORTS_W Ptr<FaceRecognizer> createLBPHFaceRecognizer(int radius=1, int neighbors=8,                                                            int grid_x=8, int grid_y=8, double threshold = DBL_MAX);


第四部分 :人脸识别(预测)  predict.cpp

1.创建人脸识别模型,为和训练相对应,仍选择特征脸模型。

Ptr<FaceRecognizer> modelPCA=createEigenFaceRecognizer();// 创建特征脸模型
2. 加载 特征脸模型器

   modelPCA->load("MyFacePcaModel.xml");

3.对测试图像进行分类
modelPCA->predict(face_test,predictPCA,confidence);  //confidence为置信度


                                       -----感谢欣赏,欢迎下边留言评论!-----