Qt + Dlib + Opencv 人脸识别(二)——功能实现

Qt + Dlib + Opencv 人脸识别(二)——功能实现

上部分我们将环境配置完成了。这里事先要说明一下,在整合各功能的时候出现了ACCESS_MASK的冲突,可以通过把各部分在×.c文件中实现,再统一放到mainwindow中调用就好。

Created with Raphaël 2.1.2 开始 检测人脸 检测到人脸 人脸对齐 人脸识别 yes no

图像捕捉

根据程序功能,需要用摄像头实时捕捉来实现图像获取。构建一个摄像头类

class GetCamera : public QObject
{
    Q_OBJECT
public:
    void Init();
    ~GetCamera(){
        if(instance != NULL){
            delete instance;
        }
        capture->release();
    }
    static GetCamera *Instance();
    cv::Mat colorImg;
    cv::Mat faceonlyImg;

private:
    static GetCamera *instance;
    cv::VideoCapture *capture;
    IplImage *frame;

public slots:
    void getFrame();
};

其中两个Mat文件分别用来存储摄像头获得到的图像和检测到的人脸。

void GetCamera::Init()
{
    capture = new cv::VideoCapture(1);
}

初始化直接调用Opencv的VideoCapture类就行,由于我使用的是外接摄像头,所以使用的参数是1。如果是是笔记本的默认摄像头,设置为0即可。

人脸检测

在人脸检测上,我直接调用了libfacedection的接口。将检测到的人脸保存在Mat faceonlyImg中。在这里要说明的是,本程序实现中只考虑了,摄像头读取的画面中,只存在一张或没有人脸。在多张人脸情况下,不能保证识别的准确性。

如果需要进一步操作的话,可以考虑通过检测到人脸的面积或者坐标来进行滤波,这个放在以后需要再实现吧。

此外,在人脸检测过程中,当人的移动速度过快,摄像头无法捕捉到人脸的时候,会报异常导致程序崩溃。调试下来估计是数组越界的原因,在保存人脸图像前,加上
if(0 <= x && 0 <= w && x + w <= faceImg.cols && 0 <= y && 0 <= h && y + h <= faceImg.rows)
就可以解决,其中 x , y , w , h 的含义就不多加解释了。

人脸识别

前面做了这么多铺垫,终于到了重头了。
人脸识别采用的是Dlib的简化版Resnet模型,具体的模型可以参考代码,就不解释了。
前面需要两个文件:
shape_predictor_68_face_landmarks.datdlib_face_recognition_resnet_model_v1.dat
前者是用来提取人脸上68个特征点,后者是Resnet的参数,这两个文件都是预先训练好的,可以直接拿来使用。
下载地址:http://dlib.net/files/

流程大概如下

Created with Raphaël 2.1.2 人脸 landmark-68标记 Resnet 128D向量

获得到的128D向量,是用来特征匹配的,匹配得对象则是预先准备好的在库的文件,需要在载入程序之前读取,或者在第一次时读取向量并保存为txt,可以避免之后再读取的麻烦。


小结

大体上这个程序就讲解完了,在Dlib方面多少有了解不到位的地方,毕竟项目紧急没有多少时间去深读源码,但是感觉dlib这个库是易于使用的。
然后,人脸识别大概在4-5Hz,准确率在正脸的情况下,基本没有识别错误吧。毕竟我们几个同学长相区别还是蛮大的。
源程序放在github上,https://github.com/lmg1994/face_recognize

猜你喜欢

转载自blog.csdn.net/tgbnm1994/article/details/80862065