Linux系统下利用OpenCV实现人脸检测和基于LBPH算法的人脸识别

        本文主要的目的是进行人脸检测和人脸识别。实验环境为Ubuntu16.04 LTS虚拟机版,技术为OpenCV,语言为c++。其中人脸检测的主要过程是从一张图片中检测出人脸可以是一个或者是多个,然后用矩形或者圆形线圈标注出来。人脸识别是基于LBPH算法实现,首先给定一张带有人脸的图片,需要提取出人脸,然后在一个图片集中进行逐个的匹配将相似度最大的一个作为匹配结果,并将此人名字打印在图片上。程序编译和执行的工具是cmake。

       下面是程序的代码和相关介绍。

1.源代码

test.cpp文件

//头文件  
#include <dirent.h>
#include<opencv2/highgui/highgui.hpp>  
#include<opencv2/contrib/contrib.hpp>  
#include<opencv2/imgproc/imgproc.hpp>  
#include<opencv2/objdetect/objdetect.hpp>  
#include<iostream>  
#include<io.h>  
  
//命名空间  
using namespace std;  
using namespace cv;  
  
CascadeClassifier faceDetect;   //人脸检测对象  
  
//函数声明  
vector<Rect> FaceDetector(Mat img);//检测人脸,并返回人脸区域  
void DrawFace(Mat img, vector<Rect> faces);//将人脸标注出来  
void GetFilesNameAndLabels(char *path, vector<string>& filesName,vector<string>& labelsInfo);

int main()  
{  
    //变量  
    Mat frame;  
    Mat src;  
    Mat facePic;  
    Mat recogPic;  
  
    vector<Rect> faces;  
    vector<string> filesName;  
    char *path = "./smalljpgset";  
    string picture;
    string pic;  
    namedWindow("1");      
    vector<Mat> trainPic;//训练图片  
    vector<int> labels;//与训练图片一一对应的标签  
    int result;  
    vector<string> labelsInfo;  
    faceDetect.load("./models/haarcascade_frontalface_alt2.xml");  
  
    Ptr<FaceRecognizer> LBPHRecog = createLBPHFaceRecognizer(1, 8 ,3, 3, 10);
    //加载人脸库  
    GetFilesNameAndLabels(path, filesName,labelsInfo); 
    cout <<filesName.size()<< endl;
    for(int i = 0; i<filesName.size(); i++)  
    {  
       pic = filesName[i];  
       src = imread(pic);       
       cvtColor(src, src, CV_RGB2GRAY);  
       trainPic.push_back(src);  
       labels.push_back(i);  
    }  

        LBPHRecog->train(trainPic, labels);         //LBP人脸识别训练函数  
        picture="./picture/Osama_bin_Laden_0001.jpg";
        frame=imread(picture);     
        recogPic = Mat::zeros(200, 200, frame.type());  
        faces = FaceDetector(frame);  
        DrawFace(frame, faces);  
        imshow("1",frame);
        waitKey(0);  
       for(size_t i = 0; i<faces.size(); i++)  
       {  
          facePic = frame(Rect(faces[i]));  
          resize(facePic, recogPic, recogPic.size());   
          cvtColor(recogPic, recogPic, CV_RGB2GRAY);   
          result = LBPHRecog->predict(recogPic);//进行识别  

          //将识别结果显示在实时画面上  
          if(result ==-1)  
{
           putText(frame, "unknow", Point(faces[i].x, faces[i].y), 3, 0.5, Scalar(0, 255, 255), 1);  
         
}
           else  
           putText(frame, labelsInfo[result], Point(faces[i].x, faces[i].y), 3, 0.5, Scalar(255, 0, 0) ,1,5);  
       
         
            imshow("1", frame);  
       
            waitKey(0);
}       
  
             return 0;
  
}  
  
vector<Rect> FaceDetector(Mat img)  
{  
    Mat src = Mat::zeros(240, 320, img.type());  
    vector<Rect> faces;  
    cvtColor(img, img, CV_RGB2GRAY);  
    resize(img, src, src.size());  
    faceDetect.detectMultiScale(img, faces, 1.2, 6, 0,Size(30,30));  
    cout <<faces.size()<< endl;
    return faces;  
}  
  
void DrawFace(Mat img, vector<Rect> faces)  
{  
    for(size_t num = 0; num<faces.size(); num++)  
    {  
        rectangle(img, Point(faces[num].x, faces[num].y),   
                       Point(faces[num].x + faces[num].width, faces[num].y + faces[num].height), Scalar(0, 255, 0), 1, 8);  
    }  
} 
void GetFilesNameAndLabels(char *path, vector<string>& filesName,vector<string>& labelsInfo)  
{  
    string p;
    DIR * dir;
    struct dirent * ptr;  
    dir = opendir(path); //打开一个目录
    while((ptr = readdir(dir)) != NULL) //循环读取目录数据
    {
         if(ptr->d_name[0] != '.')//d_name是一个char数组,存放当前遍历到的文件名  
        {  
       
         filesName.push_back(p.assign(path).append("/").append(ptr->d_name));    
         labelsInfo.push_back(ptr->d_name); 
         cout <<p << endl;

         }
    }
    closedir(dir);//关闭目录指针
}  

CmakeLists.txt

cmake_minimum_required(VERSION 2.8)
project( DisplayImage )
find_package( OpenCV REQUIRED )
add_executable( DisplayImage test.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )
cmake会用到此文件。

2.编译与执行

运行如下命令

cmake .

make

之后会生成名字为DisplayImage的可执行文件,然后执行

./DisplayImage

3.执行效果

人脸检测图:



人脸识别图:

人名信息图:



程序会输出以上信息。当程序弹窗之后,关掉之后才能继续弹窗。图三中的11和1分别代表图片集中的人数和人脸检测图片中的人脸数。

4.参考

http://blog.csdn.net/lsq2902101015/article/details/49717441

http://doc.okbase.net/zhaoweiwei/archive/238660.html

https://docs.opencv.org/master/db/df5/tutorial_linux_gcc_cmake.html




  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值