当前位置:   article > 正文

【opencv】基于opencv2的人脸识别系统_cvui 文本框

cvui 文本框

OpenCV人脸识别完整版(链接)

https://www.jianshu.com/p/232b12db4ea6

基于OepnCV的完整版的人脸识别,描述了人脸识别的全部流程,从数据收集和处理一直到最终训练出可以识别出自己的脸的模型。每一步都有代码讲解。讲解部分是原来的内容,基于opencv2。最终的放出代码是基于当下最新的OpenCV3.2。差别不大,细微的差别已经在源码放送那篇文章中写出。希望对于正在学习人脸识别的人有所帮助。


OpenCV人脸识别之一:数据收集和预处理
OpenCV人脸识别之二:模型训练
OpenCV人脸识别之三:识别自己的脸
OpenCV之识别自己的脸——C++源码放送

【opencv】基于opencv2的人脸识别系统

https://blog.csdn.net/u012679707/article/details/79510630

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

                    

                    

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

本文章写作框架如下:

1. 人脸识别流程

                        

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 );

        流程图如下:

                            


        这一模块中,有一个问题,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

        流程图如下:

                                          

        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 这表示每个特征脸的大小,一行表示一张脸的数据,维度为1030492*112
                • 1


                                       图3.1 MyFacePcaModel.xml

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

                 class CV_EXPORTS_W <span>FaceRecognizer</span> : public Algorithm
                    {
                    public:
                        //! virtual destructor
                        virtual ~FaceRecognizer() {}
                
                    <span class="hljs-comment">// Trains a FaceRecognizer.</span>
                    <span class="hljs-function">CV_WRAP <span class="hljs-keyword">virtual</span> <span class="hljs-title">void</span>&lt;<span class="hljs-title">strong</span>&gt; &lt;span&gt;<span class="hljs-title">train</span>&lt;/<span class="hljs-title">span</span>&gt;&lt;/<span class="hljs-title">strong</span>&gt;(<span class="hljs-params">InputArrayOfArrays src, InputArray labels</span>)</span> = <span class="hljs-number">0</span>;
                
                    <span class="hljs-comment">// Updates a FaceRecognizer.</span>
                    <span class="hljs-function">CV_WRAP <span class="hljs-title">void</span> &lt;span&gt;<span class="hljs-title">update</span>&lt;/<span class="hljs-title">span</span>&gt;(<span class="hljs-params">InputArrayOfArrays src, InputArray labels</span>)</span>;
                
                    <span class="hljs-comment">// Gets a prediction from a FaceRecognizer.</span>
                    <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-title">int</span> &lt;span&gt;<span class="hljs-title">predict</span>&lt;/<span class="hljs-title">span</span>&gt;(<span class="hljs-params">InputArray src</span>) <span class="hljs-keyword">const</span></span> = <span class="hljs-number">0</span>;
                
                    <span class="hljs-comment">// Predicts the label and confidence for a given sample.</span>
                    <span class="hljs-function">CV_WRAP <span class="hljs-keyword">virtual</span> <span class="hljs-keyword">void</span> <span class="hljs-title">predict</span>(<span class="hljs-params">InputArray src, CV_OUT <span class="hljs-keyword">int</span> &amp;label, CV_OUT <span class="hljs-keyword">double</span> &amp;confidence</span>) <span class="hljs-keyword">const</span></span> = <span class="hljs-number">0</span>;
                
                    <span class="hljs-comment">// Serializes this object to a given filename.</span>
                    <span class="hljs-function">CV_WRAP <span class="hljs-keyword">virtual</span> <span class="hljs-title">void</span> &lt;span&gt;<span class="hljs-title">save</span>&lt;/<span class="hljs-title">span</span>&gt;(<span class="hljs-params"><span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span>&amp; filename</span>) <span class="hljs-keyword">const</span></span>;
                
                    <span class="hljs-comment">// Deserializes this object from a given filename.</span>
                    <span class="hljs-function">CV_WRAP <span class="hljs-keyword">virtual</span> <span class="hljs-title">void</span>&lt;<span class="hljs-title">span</span>&gt; <span class="hljs-title">load</span>&lt;/<span class="hljs-title">span</span>&gt;(<span class="hljs-params"><span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span>&amp; filename</span>)</span>;
                
                    <span class="hljs-comment">// Serializes this object to a given cv::FileStorage.</span>
                    <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-keyword">void</span> <span class="hljs-title">save</span>(<span class="hljs-params">FileStorage&amp; fs</span>) <span class="hljs-keyword">const</span></span> = <span class="hljs-number">0</span>;
                
                    <span class="hljs-comment">// Deserializes this object from a given cv::FileStorage.</span>
                    <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-keyword">void</span> <span class="hljs-title">load</span>(<span class="hljs-params"><span class="hljs-keyword">const</span> FileStorage&amp; fs</span>)</span> = <span class="hljs-number">0</span>;
                
                };
                
                CV_EXPORTS_W Ptr&lt;FaceRecognizer&gt; create&lt;span&gt;EigenFace&lt;/span&gt;Recognizer(<span class="hljs-keyword">int</span> num_components = <span class="hljs-number">0</span>, <span class="hljs-keyword">double</span> threshold = DBL_MAX);
                CV_EXPORTS_W Ptr&lt;FaceRecognizer&gt; create&lt;span&gt;FisherFace&lt;/span&gt;Recognizer(<span class="hljs-keyword">int</span> num_components = <span class="hljs-number">0</span>, <span class="hljs-keyword">double</span> threshold = DBL_MAX);
                CV_EXPORTS_W Ptr&lt;FaceRecognizer&gt; create&lt;span&gt;LBPHFace&lt;/span&gt;Recognizer(<span class="hljs-keyword">int</span> radius=<span class="hljs-number">1</span>, <span class="hljs-keyword">int</span> neighbors=<span class="hljs-number">8</span>,
                                                                        <span class="hljs-keyword">int</span> grid_x=<span class="hljs-number">8</span>, <span class="hljs-keyword">int</span> grid_y=<span class="hljs-number">8</span>, <span class="hljs-keyword">double</span> threshold = DBL_MAX);
                
                • 1
                • 2
                • 3
                • 4
                • 5
                • 6
                • 7
                • 8
                • 9
                • 10
                • 11
                • 12
                • 13
                • 14
                • 15
                • 16
                • 17
                • 18
                • 19
                • 20
                • 21
                • 22
                • 23
                • 24
                • 25
                • 26
                • 27
                • 28
                • 29
                • 30
                • 1
                • 2
                • 3
                • 4
                • 5



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

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

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

                     modelPCA->load(“MyFacePcaModel.xml”);

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


                    ----------------------------------------【全部实例代码】----------------------------------------------

                    第一部分:main.cpp

                    /*
                    Project Name:FaceRecognition
                    Author:Lisa
                    Data:2017_12
                    Version:V1
                    • 1
                    • 2
                    • 3
                    • 4
                    • 5

                    Abstract:
                    the faceRecognition system includes 3 modules:
                    1.capture.cpp ->capture face Image and Detect face
                    2.train.cpp ->train face module
                    3.predict.cpp ->capture face image,face detection,face recognition

                    Statement:
                    You are free to use, change, or redistribute the code in any way you wish for
                    non-commercial purposes, but please maintain the name of the original author.
                    This code comes with no warranty(保证) of any kind.
                    */
                    //#include"stdafx.h"
                    #include<opencv2/opencv.hpp>
                    #include<opencv2/highgui/highgui.hpp>
                    #include<opencv2/core/core.hpp>
                    #include<opencv2/imgproc/imgproc.hpp>
                    #include<iostream>
                    #include<fstream> //包含ifstream
                    #include"opencv2/cvui/cvui.h"

                    #include"capture.hpp"
                    #include"train.hpp"
                    #include"predict.hpp"
                    #include<windows.h>

                    using namespace cv;
                    using namespace std;
                    //using namespace cvui;

                    #define WINDOW_NAME “Face Recognition System ByLISA”
                    // 采集到的图片保存地址
                    const string savePath=“F:\opencv_project\faceRecognition\ORL\prePhoto\1.pgm”;
                    /******************************* main() ***************************************************************/
                    Mat Frame;
                    int main(int argc,char *argv[])
                    {
                    system(“color 5E”);
                    //Mat img=imread(“lanyangyang.jpg”);

                    namedWindow(WINDOW_NAME);
                    cvui::init(WINDOW_NAME);
                    Frame=Mat(<span class="hljs-number">320</span>,<span class="hljs-number">500</span>,CV_8UC3);
                    Frame = cv::Scalar(<span class="hljs-number">200</span>,<span class="hljs-number">20</span>,<span class="hljs-number">200</span>);   <span class="hljs-comment">//颜色填充49, 52, 49</span>
                    
                    cvui::window(Frame,<span class="hljs-number">350</span>,<span class="hljs-number">30</span>,<span class="hljs-number">100</span>,<span class="hljs-number">132</span>,<span class="hljs-string">"predict photo"</span>);
                    cvui::window(Frame,<span class="hljs-number">350</span>,<span class="hljs-number">165</span>,<span class="hljs-number">100</span>,<span class="hljs-number">132</span>,<span class="hljs-string">"predict result"</span>);
                    
                    <span class="hljs-keyword">while</span>(<span class="hljs-number">1</span>)
                    
                    • 1
                    • 2
                    • 3
                    • 4
                    • 5
                    • 6
                    • 7
                    • 8
                    • 9

                    {

                    <span class="hljs-keyword">bool</span> buttonCapture=cvui::button(Frame,<span class="hljs-number">50</span>,<span class="hljs-number">100</span>,<span class="hljs-string">"Capture"</span>); 
                    <span class="hljs-keyword">bool</span> buttonTrain=cvui::button(Frame,<span class="hljs-number">50</span>,<span class="hljs-number">130</span>,<span class="hljs-string">"Train"</span>);
                    <span class="hljs-keyword">bool</span> buttonPredict=cvui::button(Frame,<span class="hljs-number">50</span>,<span class="hljs-number">160</span>,<span class="hljs-string">"Predict"</span>);
                    
                    
                    <span class="hljs-keyword">if</span>(buttonCapture) { 
                    	Mat capPhoto;
                    	<span class="hljs-keyword">if</span>(photoCapture(capPhoto)) cvui::text(Frame, <span class="hljs-number">150</span>, <span class="hljs-number">100</span>, <span class="hljs-string">"capture is sucessful!"</span>); 
                    	<span class="hljs-keyword">else</span>  cvui::text(Frame, <span class="hljs-number">150</span>, <span class="hljs-number">100</span>, <span class="hljs-string">"capture failed!"</span>);
                    
                    }
                    <span class="hljs-keyword">if</span>(buttonTrain)  {
                    	<span class="hljs-keyword">if</span>(train()) cvui::text(Frame, <span class="hljs-number">150</span>, <span class="hljs-number">130</span>, <span class="hljs-string">"train is sucessful!"</span>);
                    	<span class="hljs-keyword">else</span>              cvui::text(Frame, <span class="hljs-number">150</span>, <span class="hljs-number">100</span>, <span class="hljs-string">"train failed!"</span>);
                    }
                    <span class="hljs-keyword">if</span>(buttonPredict) { 
                    	  cvui::<span class="hljs-built_in">printf</span>(Frame, <span class="hljs-number">150</span>, <span class="hljs-number">160</span>,<span class="hljs-number">0.4</span>, <span class="hljs-number">0x00ff00</span>, <span class="hljs-string">"predict result is    "</span>);
                    
                    	Mat predictPhoto;<span class="hljs-comment">//待识别照片</span>
                    	<span class="hljs-keyword">int</span> predictResult;<span class="hljs-comment">//预测结果</span>
                    	predict(predictPhoto,predictResult);
                    	imwrite(savePath,predictPhoto);
                    	cvui::<span class="hljs-built_in">printf</span>(Frame, <span class="hljs-number">150</span>, <span class="hljs-number">160</span>,<span class="hljs-number">0.4</span>, <span class="hljs-number">0x00ff00</span>, <span class="hljs-string">"predict result is %d"</span>,predictResult);
                        	
                    	<span class="hljs-built_in">string</span> fileName=<span class="hljs-string">"F:\\opencv_project\\faceRecognition\\ORL\\s"</span>;
                    	fileName+=to_string(predictResult+<span class="hljs-number">1</span>); <span class="hljs-comment">//number To string</span>
                    	fileName+=<span class="hljs-string">"\\1.pgm"</span>;
                    	<span class="hljs-built_in">cout</span>&lt;&lt;fileName&lt;&lt;<span class="hljs-built_in">endl</span>;
                    	Mat img1=imread(fileName);
                    	fileName=<span class="hljs-string">"0"</span>;<span class="hljs-comment">//文件路径清零(要在获取完以后再清零)</span>
                    	
                    	<span class="hljs-comment">// 在preROI区显示照片</span>
                    	Mat prePhoto=imread(savePath);<span class="hljs-comment">//读取采集图 </span>
                    	Mat preROI=Frame(Rect(<span class="hljs-number">353</span>,<span class="hljs-number">50</span>,predictPhoto.cols,predictPhoto.rows)); <span class="hljs-comment">//250 200</span>
                    	resize(prePhoto,preROI,Size(<span class="hljs-number">92</span>,<span class="hljs-number">112</span>) );
                    	<span class="hljs-comment">// 在resultROI区显示照片</span>
                    	Mat resultROI=Frame(Rect(<span class="hljs-number">353</span>,<span class="hljs-number">185</span>,img1.cols,img1.rows)); <span class="hljs-comment">//250 200</span>
                    	resize(img1,resultROI,Size(<span class="hljs-number">92</span>,<span class="hljs-number">112</span>) );  	<span class="hljs-comment">//另一种方法:img1.copyTo(resultROI,img1);</span>
                    	<span class="hljs-comment">//imshow("Result",img1);	</span>
                    }
                    cvui::update();
                    imshow(WINDOW_NAME,Frame);
                    <span class="hljs-keyword">if</span> (cv::waitKey(<span class="hljs-number">20</span>) == <span class="hljs-number">27</span>) <span class="hljs-keyword">break</span>;  
                    
                    • 1
                    • 2
                    • 3
                    • 4
                    • 5
                    • 6
                    • 7
                    • 8
                    • 9
                    • 10
                    • 11
                    • 12
                    • 13
                    • 14
                    • 15
                    • 16
                    • 17
                    • 18
                    • 19
                    • 20
                    • 21
                    • 22
                    • 23
                    • 24
                    • 25
                    • 26
                    • 27
                    • 28
                    • 29
                    • 30
                    • 31
                    • 32
                    • 33
                    • 34
                    • 35
                    • 36
                    • 37
                    • 38
                    • 39
                    • 40
                    • 41
                    • 42
                    • 43

                    }
                    return 0;
                    }

                    #if 0
                    // 在指定区域显示图片
                    Mat mask=imread(“lanyangyang.jpg”);
                    Mat winROI=Frame(Rect(50,120,mask.cols,mask.rows));
                    img.copyTo(winROI,mask);
                    #endif


                    第二部分:capture.cpp

                    // capture.cpp
                    
                    • 1

                    #include"capture.hpp"
                    #include<windows.h>

                    bool photoCapture(Mat &capPhoto )
                    {

                    /***************************************** 1.打开默认摄像头 ********************************************************/
                    VideoCapture cap(0); //打开默认摄像头
                    if(! cap.isOpened())
                    {
                    cout<<“camera open fail”<<endl;
                    exit(-1);
                    }

                    <span class="hljs-keyword">int</span> i=<span class="hljs-number">1</span>;
                    Mat frame; <span class="hljs-comment">// 关联视频流</span>
                    Mat frameGray;<span class="hljs-comment">// frame的灰度图</span>
                    Mat frameROI; <span class="hljs-comment">// frameGray的ROI区</span>
                    Mat face;
                    <span class="hljs-built_in">vector</span>&lt;Rect&gt; faces;
                    
                    <span class="hljs-comment">/*********************************** 2.加载人脸检测器,加载人脸模型器******************************/</span>
                    CascadeClassifier cascade;<span class="hljs-comment">//建立级联分类器</span>
                    cascade.load(<span class="hljs-string">"haarcascade_frontalface_alt2.xml"</span>);	<span class="hljs-comment">// 加载训练好的 人脸检测器(.xml)</span>
                    <span class="hljs-keyword">while</span>(<span class="hljs-number">1</span>)
                    {
                    	cap&gt;&gt;frame;
                    	namedWindow(<span class="hljs-string">"frame"</span>);
                    	imshow(<span class="hljs-string">"frame"</span>,frame);  <span class="hljs-comment">// 显示每一帧图像</span>
                    	<span class="hljs-comment">//cvui::update();</span>
                        <span class="hljs-comment">//imshow(WINDOW_NAME,Frame);</span>
                    	<span class="hljs-built_in">string</span> filename=format(<span class="hljs-string">"F:\\opencv_project\\faceRecognition\\ORL\\s42\\%d.pgm"</span>,i);
                    
                    	<span class="hljs-keyword">char</span> key=waitKey(<span class="hljs-number">30</span>);;
                    	<span class="hljs-keyword">switch</span>(key) <span class="hljs-comment">// 按下采集按钮</span>
                    	{
                    <span class="hljs-keyword">case</span> <span class="hljs-string">'p'</span>:
                    	
                    	cvtColor(frame,frameGray,CV_BGR2GRAY);
                    	<span class="hljs-comment">//imshow("frameGray",frameGray);</span>
                    	
                    
                    	<span class="hljs-comment">/*********************************** 3.人脸检测 ******************************/</span>
                        cascade.detectMultiScale(frameGray,faces,<span class="hljs-number">1.2</span>, <span class="hljs-number">2</span>,<span class="hljs-number">0</span> |  CV_HAAR_FIND_BIGGEST_OBJECT );
                    	<span class="hljs-keyword">if</span>(faces.size()&gt;<span class="hljs-number">0</span>)
                    	{
                    	  <span class="hljs-keyword">for</span>(<span class="hljs-keyword">size_t</span> ii=<span class="hljs-number">0</span>;ii&lt;faces.size();ii++)
                    	  {   <span class="hljs-comment">// setImgROI</span>
                    		frameROI=frameGray(faces[ii]); <span class="hljs-comment">// 为frame_temp设置了ROI区域 -&gt; Mat imgROI=img( Rect);</span>
                    	  }	
                          resize(frameROI,face,Size(<span class="hljs-number">92</span>,<span class="hljs-number">112</span>));
                    	  imwrite(filename,face);
                    	  imshow(<span class="hljs-string">"photo"</span>,face);
                    	  face.copyTo(capPhoto); <span class="hljs-comment">// 将采集到的图片copy给capPhoto</span>
                    	  i++;
                    	  waitKey(<span class="hljs-number">500</span>);
                    	  destroyWindow(<span class="hljs-string">"photo"</span>);
                    	}
                    	<span class="hljs-keyword">else</span> 
                    	{
                    		<span class="hljs-comment">//项目属性的常规项修改字符集,选择为多字符集 ,原为Unicode</span>
                    		MessageBox(GetForegroundWindow(),<span class="hljs-string">"valid capture!please retry!"</span>,<span class="hljs-string">"Warning"</span>,<span class="hljs-number">1</span>); <span class="hljs-comment">//MessageBox </span>
                             <span class="hljs-comment">//printf("%d\n",x); </span>
                    	}
                    	<span class="hljs-keyword">break</span>;
                    
                    <span class="hljs-keyword">case</span> <span class="hljs-string">'P'</span>:
                    	cvtColor(frame,frameGray,CV_BGR2GRAY);
                    	<span class="hljs-comment">/*********************************** 3.人脸检测 ******************************/</span>
                        cascade.detectMultiScale(frameGray,faces,<span class="hljs-number">1.2</span>, <span class="hljs-number">2</span>,<span class="hljs-number">0</span> |  CV_HAAR_FIND_BIGGEST_OBJECT );
                    	<span class="hljs-keyword">if</span>(faces.size()&gt;<span class="hljs-number">0</span>)
                    	{
                    	<span class="hljs-keyword">for</span>(<span class="hljs-keyword">size_t</span> ii=<span class="hljs-number">0</span>;ii&lt;faces.size();ii++)
                    	{   <span class="hljs-comment">// setImgROI</span>
                    		frameROI=frameGray(faces[ii]); <span class="hljs-comment">// 为frame_temp设置了ROI区域 -&gt; Mat imgROI=img( Rect);</span>
                    	}
                    	 resize(frameROI,face,Size(<span class="hljs-number">92</span>,<span class="hljs-number">112</span>));
                    	 imwrite(filename,face);
                    	 imshow(<span class="hljs-string">"photo"</span>,face);
                    	 i++;
                    	 waitKey(<span class="hljs-number">500</span>);
                    	 destroyWindow(<span class="hljs-string">"photo"</span>);
                    	}
                    	<span class="hljs-keyword">break</span>;
                    	
                    <span class="hljs-keyword">default</span>: <span class="hljs-keyword">break</span>;
                    	}
                    	<span class="hljs-keyword">if</span>(i&gt;=(captureCount+<span class="hljs-number">1</span>)) 
                    	{ 
                    		<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"capture is successful!"</span>&lt;&lt;<span class="hljs-built_in">endl</span>; 
                    		MessageBox(GetForegroundWindow(),<span class="hljs-string">"capture is successful!"</span>,<span class="hljs-literal">NULL</span>,<span class="hljs-number">1</span>); <span class="hljs-comment">//MessageBox</span>
                    		<span class="hljs-keyword">break</span>;
                    	}
                    }
                    
                    	
                    destroyWindow(<span class="hljs-string">"frame"</span>);
                    <span class="hljs-keyword">if</span>(i&gt;=(captureCount+<span class="hljs-number">1</span>)) <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
                    <span class="hljs-keyword">else</span>                <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
                    
                    • 1
                    • 2
                    • 3
                    • 4
                    • 5
                    • 6
                    • 7
                    • 8
                    • 9
                    • 10
                    • 11
                    • 12
                    • 13
                    • 14
                    • 15
                    • 16
                    • 17
                    • 18
                    • 19
                    • 20
                    • 21
                    • 22
                    • 23
                    • 24
                    • 25
                    • 26
                    • 27
                    • 28
                    • 29
                    • 30
                    • 31
                    • 32
                    • 33
                    • 34
                    • 35
                    • 36
                    • 37
                    • 38
                    • 39
                    • 40
                    • 41
                    • 42
                    • 43
                    • 44
                    • 45
                    • 46
                    • 47
                    • 48
                    • 49
                    • 50
                    • 51
                    • 52
                    • 53
                    • 54
                    • 55
                    • 56
                    • 57
                    • 58
                    • 59
                    • 60
                    • 61
                    • 62
                    • 63
                    • 64
                    • 65
                    • 66
                    • 67
                    • 68
                    • 69
                    • 70
                    • 71
                    • 72
                    • 73
                    • 74
                    • 75
                    • 76
                    • 77
                    • 78
                    • 79
                    • 80
                    • 81
                    • 82
                    • 83
                    • 84
                    • 85

                    }


                    第三部分:train.cpp

                    // train.cpp
                    
                    • 1

                    #include"train.hpp"
                    #include<windows.h>

                    bool train()
                    {
                    string csvFile=“at.txt”;
                    vector<Mat> images;
                    vector<int> labels;

                    <span class="hljs-comment">// [1]读取csv文件</span>
                    <span class="hljs-keyword">try</span>
                    {
                    read_csv(csvFile,images,labels,CountMax,CountMin,<span class="hljs-string">';'</span>); <span class="hljs-comment">//读取csvFile中所有的img和label</span>
                    }
                    <span class="hljs-keyword">catch</span>(cv::Exception&amp; e) <span class="hljs-comment">// ???????????????????????????????????????????????????</span>
                    {                  <span class="hljs-comment">// cerr:输出到标准错误的ostream对象,常用于程序错误信息</span>
                    <span class="hljs-built_in">cerr</span>&lt;&lt;<span class="hljs-string">"Error opening file\" "</span>&lt;&lt;csvFile &lt;&lt;<span class="hljs-string">"\".reason: "</span>&lt;&lt;e.msg&lt;&lt;<span class="hljs-built_in">endl</span>; <span class="hljs-comment">//异常 发生的原因</span>
                    <span class="hljs-built_in">exit</span>(<span class="hljs-number">-1</span>);
                    }
                    
                    
                    <span class="hljs-comment">// 若未读取到足够图片,也退出</span>
                    <span class="hljs-keyword">if</span>(images.size() &lt;=<span class="hljs-number">1</span>)
                    {
                    	<span class="hljs-built_in">string</span> errMsg=<span class="hljs-string">"THis demo needs at least 2 images to work.please add images!"</span>;
                    	CV_Error(CV_StsError,errMsg);
                    
                    }
                    <span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"train1.读取ok"</span>&lt;&lt;<span class="hljs-built_in">endl</span>;
                    
                    <span class="hljs-comment">// 训练数据,并将训练好的人脸模型保存到.xml中</span>
                    <span class="hljs-comment">/*
                    Ptr&lt;&gt;为模板类,定义model为指向FaceRecognizer类的指针。model为指针!
                    */</span>
                    Ptr&lt;FaceRecognizer&gt; model=createEigenFaceRecognizer(<span class="hljs-number">20</span>); <span class="hljs-comment">// 创建特征脸模型 20张主成分脸</span>
                    model-&gt;train(images,labels); <span class="hljs-comment">//训练</span>
                    model-&gt;save(<span class="hljs-string">"MyFacePcaModel.xml"</span>); <span class="hljs-comment">//将训练模型保存到MyFacePcaModel.xml</span>
                    
                    <span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"train2.创建脸模型ok"</span>&lt;&lt;<span class="hljs-built_in">endl</span>;
                    MessageBox(GetForegroundWindow(),<span class="hljs-string">"train is sucessful!"</span>,<span class="hljs-literal">NULL</span>,<span class="hljs-number">1</span>); <span class="hljs-comment">//MessageBox </span>
                    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
                    
                    }
                    
                    
                    <span class="hljs-comment">/*
                    
                    • 1
                    • 2
                    • 3
                    • 4
                    • 5
                    • 6
                    • 7
                    • 8
                    • 9
                    • 10
                    • 11
                    • 12
                    • 13
                    • 14
                    • 15
                    • 16
                    • 17
                    • 18
                    • 19
                    • 20
                    • 21
                    • 22
                    • 23
                    • 24
                    • 25
                    • 26
                    • 27
                    • 28
                    • 29
                    • 30
                    • 31
                    • 32
                    • 33
                    • 34
                    • 35
                    • 36
                    • 37

                    函数:static void read_csv(const string& filename,vector<Mat>images, vector<int> labels,int CountMax,int CountMin, char separator=’;’)
                    功能:读取csv文件的图像路径和标签。主要使用stringstream和getline()
                    参数说明:filename–要读取的csv文件
                    images----读取的图片(向量)
                    labels----读取的图片对应标签 (向量)
                    CountMax,int CountMin–读取的每一类别的图片下标的最大值和最小值(默认每个类别共10张照片)
                    separator-分隔符,起控制读取的作用。可自定义为逗号空格等,(此程序中)默认为分号
                    返回值:空
                    /
                    /

                    备注:(函数内部涉及到的部分类和方法说明)

                    1. stringstream:字符串流。
                      功能:将内存中的对象与流绑定。

                    2. getline():
                      函数原型:istream &getline( ifstream &input,string &out,char dielm)
                      参数说明:Input–输入文件
                      out----输出字符串
                      dielm–读取到该字符停止(起到控制作用),默认是换行符‘\n’
                      功能: 读取文件Input中的字符串到out中。
                      返回值:返回Input,若是文件末尾会返回文件尾部标识eof

                    3. ifstream: 从硬盘打开文件(读取),从磁盘输入文件,读到内存中
                      ofstream: 从内存打开文件(读取),从内存输入文件,读到磁盘中)
                      */
                      static void read_csv(const string& filename,vector<Mat>& images, vector<int>& labels,int max,int min,char separator=’;’)
                      {
                      std::ifstream file(filename.c_str(),ifstream::in); // 以in模式(读取文件模式)打开文件 ,实际是将filename文件关联给 流file !!!!!!!!!!!!!!!!!! filename.c_str()

                      if(! file)
                      {
                      string error_message=“No valid input file was given,please check the given filename”;
                      CV_Error(CV_StsBadArg,error_message);

                      }
                      int ii=0;

                      /读取文件.txt内容******/
                      string line,path,label;
                      // [1]读取file文件中的一行字符串给 line
                      while( getline(file,line,’\n’) ) // 控制:直到读到file文件末尾(eof标识),才跳出while
                      {
                      // [2]将line整行字符串读取到lines(流)中
                      stringstream lines(line); //区别->lines是流,读取字符时,指针会随流而动;而line是string,固定的,下文中的读取每次都是从line头开始
                      // [3]读取文件中的路径和标签
                      getline(lines,path,separator); //此时光标已走到path之后的位置(即;分号处)
                      getline(lines,label);
                      // [4]将图片和标签加入imgs 和 labels
                      if( (path.empty()==0) && (label.empty() ==0))
                      {
                      if(ii%10<=max && ii%10>=min) //默认每个类别共10张照片
                      {
                      Mat img=imread(path,0); //第二个参数为0 !!!
                      //Mat img = imread(ImageFileAddress, CV_LOAD_IMAGE_GRAYSCALE),CV_LOAD_IMAGE_GRAYSCALE值为 0,指灰图(原本为“CV_LOAD_IMAGE_UNCHANGED”)
                      if(img.data!=0 )
                      {
                      images.push_back( img ); // 将图片 添加到images中
                      labels.push_back( atoi(label.c_str() ) );
                      }
                      }
                      if(ii<9) ii++;
                      else ii=0;

                       }
                      
                      • 1

                      }
                      }

                        第四部分:predict.cpp

                        // predict.cpp
                        
                        • 1
                        • 1

                      #include"predict.hpp"
                      #include<windows.h>

                      using namespace cv;
                      using namespace std;

                      // void predict();
                      void predict(Mat &predictPhoto,int& predictPCA)
                      {
                      /*********************************** 1.打开默认摄像头******************************/
                      VideoCapture cap(0); //
                      if(! cap.isOpened())
                      {
                      cout<<“camera open fail”<<endl;
                      exit(-1);
                      }

                      <span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"predict 1.ok"</span>&lt;&lt;<span class="hljs-built_in">endl</span>;
                      
                      Mat frame;
                      Mat gray; <span class="hljs-comment">// 灰度图</span>
                      <span class="hljs-function"><span class="hljs-built_in">vector</span>&lt;Rect&gt; <span class="hljs-title">faces</span><span class="hljs-params">(<span class="hljs-number">0</span>)</span></span>; <span class="hljs-comment">//矩形向量,存放检测出的人脸</span>
                      <span class="hljs-comment">/*********************************** 2.加载人脸检测器,加载人脸模型器******************************/</span>
                      <span class="hljs-comment">//建立级联分类器</span>
                      CascadeClassifier cascade;
                      <span class="hljs-comment">// 加载训练好的 人脸检测器(.xml)</span>
                      cascade.load(<span class="hljs-string">"haarcascade_frontalface_alt2.xml"</span>);
                      
                      Ptr&lt;FaceRecognizer&gt; modelPCA=createEigenFaceRecognizer();<span class="hljs-comment">// 创建特征脸模型</span>
                      <span class="hljs-comment">// 加载 特征脸模型器</span>
                      modelPCA-&gt;load(<span class="hljs-string">"MyFacePcaModel.xml"</span>);
                      
                      <span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"predict 2.ok"</span>&lt;&lt;<span class="hljs-built_in">endl</span>;
                      <span class="hljs-keyword">int</span> key;
                      Mat capFace;
                      <span class="hljs-keyword">while</span>(<span class="hljs-number">1</span>)
                      {
                      	cap&gt;&gt;frame; <span class="hljs-comment">//将获取到的每一帧图像 写入 frame;</span>
                      	namedWindow(<span class="hljs-string">"frame"</span>);
                      	imshow(<span class="hljs-string">"frame"</span>,frame);   <span class="hljs-comment">// 显示摄像头</span>
                      	key=waitKey(<span class="hljs-number">50</span>);
                      	<span class="hljs-keyword">if</span>(key==<span class="hljs-string">'p'</span>||key==<span class="hljs-string">'P'</span>) 
                      	{
                      	capFace=frame.clone();
                      	<span class="hljs-comment">// rgb To gray</span>
                      	cvtColor(frame,gray,CV_BGR2GRAY);
                      	<span class="hljs-comment">// 直方图均衡化,提高图像质量</span>
                      	equalizeHist(gray,gray);
                      	<span class="hljs-comment">/*********************************** 3.人脸检测 ******************************/</span>
                      	cascade.detectMultiScale(gray,faces,<span class="hljs-number">1.2</span>, <span class="hljs-number">2</span>,<span class="hljs-number">0</span> |  CV_HAAR_FIND_BIGGEST_OBJECT );
                         
                      	<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"detect face number is :"</span>&lt;&lt;faces.size()&lt;&lt;<span class="hljs-built_in">endl</span>;
                      	<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"predict 3.ok"</span>&lt;&lt;<span class="hljs-built_in">endl</span>;
                      	<span class="hljs-keyword">if</span>(faces.size()&gt;<span class="hljs-number">0</span>)
                      	{
                      	<span class="hljs-comment">/************************************* 4.人脸识别 ******************************/</span>
                      	Mat face_temp,face_test;
                      	<span class="hljs-keyword">for</span>(<span class="hljs-keyword">size_t</span> i=<span class="hljs-number">0</span>;i&lt;faces.size();i++)
                      	{   			
                      		<span class="hljs-comment">// setImgROI</span>
                      		face_temp=gray(faces[i]); <span class="hljs-comment">// 为Gray设置了ROI区域 -&gt; Mat imgROI=img( Rect);</span>
                      	
                      	}	
                      	<span class="hljs-comment">// 调整大小为112*92</span>
                      	resize(face_temp,face_test,Size(<span class="hljs-number">92</span>,<span class="hljs-number">112</span>));
                      	namedWindow(<span class="hljs-string">"capFace"</span>);
                      	imshow(<span class="hljs-string">"capFace"</span>,face_test);
                      	face_test.copyTo(predictPhoto);
                      			
                      	<span class="hljs-comment">// 测试图应该为灰度图</span>
                      	<span class="hljs-keyword">double</span> confidence;
                      	modelPCA-&gt;predict(face_test,predictPCA,confidence);
                      	<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"the predict result is "</span>&lt;&lt; predictPCA&lt;&lt;<span class="hljs-built_in">endl</span>&lt;&lt;<span class="hljs-string">"confidence is "</span>&lt;&lt;confidence&lt;&lt;<span class="hljs-built_in">endl</span>;
                      	waitKey(<span class="hljs-number">2000</span>);
                      	<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"predict 4.ok"</span>&lt;&lt;<span class="hljs-built_in">endl</span>;
                      	<span class="hljs-keyword">break</span>;
                      	}
                      	<span class="hljs-keyword">else</span>
                      	{
                      		<span class="hljs-comment">//项目属性的常规项修改字符集,选择为多字符集 ,原为Unicode</span>
                      		MessageBox(GetForegroundWindow(),<span class="hljs-string">"valid capture!please retry!"</span>,<span class="hljs-string">"Warning"</span>,<span class="hljs-number">1</span>); <span class="hljs-comment">//MessageBox </span>
                      	}
                      	
                      	}
                      }
                      destroyWindow(<span class="hljs-string">"frame"</span>);
                      destroyWindow(<span class="hljs-string">"capFace"</span>);
                      
                      • 1
                      • 2
                      • 3
                      • 4
                      • 5
                      • 6
                      • 7
                      • 8
                      • 9
                      • 10
                      • 11
                      • 12
                      • 13
                      • 14
                      • 15
                      • 16
                      • 17
                      • 18
                      • 19
                      • 20
                      • 21
                      • 22
                      • 23
                      • 24
                      • 25
                      • 26
                      • 27
                      • 28
                      • 29
                      • 30
                      • 31
                      • 32
                      • 33
                      • 34
                      • 35
                      • 36
                      • 37
                      • 38
                      • 39
                      • 40
                      • 41
                      • 42
                      • 43
                      • 44
                      • 45
                      • 46
                      • 47
                      • 48
                      • 49
                      • 50
                      • 51
                      • 52
                      • 53
                      • 54
                      • 55
                      • 56
                      • 57
                      • 58
                      • 59
                      • 60
                      • 61
                      • 62
                      • 63
                      • 64
                      • 65
                      • 66
                      • 67
                      • 68
                      • 69
                      • 70

                      }


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


                      声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/945788
                      推荐阅读
                      相关标签
                        

                      闽ICP备14008679号