浅谈OpenCV特定人脸识别

做一个简单的opencv特定人像识别demo,用于学习opencv基础

需要用到的头文件

#include <iostream>
#include <opencv2/opencv.hpp>
#include <face.hpp>
 
using namespace std;
using namespace cv; //namespace of opencv
using namespace cv::face;

 

创建两个容器,用与储存图片数据与标签

1 std::vector<Mat> datas;     //存放图片数据的同期
2 std::vector<int> lables;    //存放标签的容器--整型    

读取灰度图数据到容器中

 1     //读取事先准备好用于人像识别的图片灰度数据,并存放到容器中
 2     Mat aimage = imread("./face/a.png", IMREAD_GRAYSCALE);
 3     resize(aimage, aimage, Size(200, 200) );    //图片尺寸要保持一致
 4     datas.push_back(aimage);
 5     lables.push_back(10);
 6 
 7     //读取图片灰度数据,并存放到容器中
 8     Mat bimage = imread("./face/b.png", IMREAD_GRAYSCALE);
 9     resize(bimage, bimage, Size(200, 200) );    //图片尺寸要保持一致
10     datas.push_back(bimage);
11     lables.push_back(11);
12 
13     //读取图片灰度数据,并存放到容器中
14     Mat cimage = imread("./face/c.png", IMREAD_GRAYSCALE);
15     resize(cimage, cimage, Size(200, 200) );    //图片尺寸要保持一致
16     datas.push_back(cimage);
17     lables.push_back(12);
18 
19     //读取同一个人的5张图片灰度数据
20     for(int i=0; i<5; i++)
21     {
22         char path[128];
23         sprintf(path, "./face/%d.jpg", i);
24         Mat image = imread(path, IMREAD_GRAYSCALE);
25         resize(image, image, Size(200, 200) );    //图片尺寸要保持一致
26         datas.push_back(image);
27         lables.push_back(13);
28     }
    //创建训练模型
    Ptr<FaceRecognizer> model = EigenFaceRecognizer::create();
    model->train(datas, lables);    //训练
    model->save("./model.xml");     //保存训练数据
     //创建训练模型
    Ptr<FaceRecognizer> model = EigenFaceRecognizer::create();
    model->train(datas, lables);    //训练
    model->save("./model.xml");     //保存训练内容数据,下次可直接读取
    //定义存储拍摄照片数据的对象
    Mat videoimage, grayimage;
    VideoCapture cap;
    //打开摄像头
    if(!cap.open(0))
    {
        cout << "open camera device failed" << endl;
    }
    //创建人脸识别对象
    CascadeClassifier cascad;
    //读取opencv提供的人脸特征识别文件
    cascad.load("D:/Qt/5.12/5.12.0/opencv64/etc/haarcascades/haarcascade_frontalface_default.xml");
    //创建用于储存识别到的人脸图像数据的容器
    std::vector<Rect> faceRect;
    while(1)
    {
        cap >> videoimage;  //拍摄一张照片
        if(videoimage.data == NULL) //说明拍摄失败
            continue;

        //转为灰度图,便于图像处理
        cvtColor(videoimage, grayimage, CV_RGB2GRAY);  
        //判断照片中是否有人脸出现,若有人脸出现则储存在容器当中
        cascad.detectMultiScale(grayimage, faceRect, 1.1, 3, 0, Size(5,5));

        if(faceRect.size() > 0) //说明检测到一张人脸
        {
            Mat faceimage = videoimage(faceRect[0]);    //从照片中截取人脸部分
            resize(faceimage, faceimage, Size(200, 200) ); //须与模型中的照片尺寸大小保持一致!
            cvtColor(faceimage, faceimage, CV_RGB2GRAY);  //转为灰度图
            int lable = model->predict(faceimage);  //将截取到的照片与训练模型中的照片相比对,如果比对成功则返回该照片对应的标签(一个整型)

            if(lable == 10) //与第一张照片比对成功
            {
                putText(videoimage, "leonardo", Point(faceRect[0].x, faceRect[0].y),\
                        FONT_HERSHEY_SIMPLEX, 2, Scalar(0,0,255));
            }
            else if(lable == 12) //与第三张照片比对成功
            {
                putText(videoimage, "eason", Point(faceRect[0].x, faceRect[0].y),\
                        FONT_HERSHEY_SIMPLEX, 2,Scalar(0,0,255));
            }
            else if(lable == 13)
            {
                putText(videoimage, "David Lai", Point(faceRect[0].x, faceRect[0].y),\
                        FONT_HERSHEY_SIMPLEX, 2, Scalar(0,0,255));
            }

            Point point(faceRect[0].x+faceRect[0].width/2, faceRect[0].y+faceRect[0].height/2);
            //画一个圆将识别到的人脸圈住
            circle(videoimage, point, faceRect[0].width/2, Scalar(0,0,255));
        }
         //显示拍摄到的照片  
        imshow("video", videoimage);
        //wait for any pressed key
        waitKey(10);
    }    

识别效果展示如下图

本demo可以做到粗略的识别,会存在误判的情况

posted @ 2020-04-03 22:02  eason-chen  阅读(588)  评论(0)    收藏  举报