基于CNN卷积神经网络的人脸识别

一、利用卷积神经网络进行人脸检测,称作CFF(卷积人脸搜索)

卷积神经网络人脸识别的大致流程:

1)对本地人脸进行特征提取

2)打开摄像头(opencv)

3)从cap获取信息

4)找人脸

5)对人脸进行特征提取

6)与已经存储的特征进行比对

7)如果余弦夹角相近,使得余弦值大于阈值,则判断成功。

二、卷积神经网络人脸识别(C++实现):

FaceRecognition.h

#pragma once
#include <opencv2/dnn.hpp>
#include <opencv2/opencv.hpp>
#include <iostream>

class CFaceRecognition
{
private:
    const size_t m_nWidth;
    const size_t m_nHeight;
    const double m_dScaleFactor;
    const cv::Scalar m_meanVal;
    float m_fConfidenceThreshold;
    cv::dnn::Net m_net;             //检测人脸
    cv::dnn::Net m_netRecogn;   //提取人脸特征
    std::vector<cv::Mat*> m_fv;   //存储人脸特征
    std::vector<std::string> m_labels; //存储标签
public:
    CFaceRecognition();
    CFaceRecognition(double confidence);
    ~CFaceRecognition();
    void train(cv::Mat sample,std::string label);
    double  predict(cv::Mat & src);
private:
    void recognize_face(cv::Mat& face, cv::Mat* vec);
    float compare(cv::Mat* vec_1,cv::Mat* vec_2);
/*    float sumVec(cv::Mat& vec);
    float dotVec(cv::Mat& vec_1, cv::Mat& vec_2);
    float normVec(cv::Mat& vec_1, cv::Mat& vec_2);*/
};

FaceRecognition.c

     return 0.0;
    float dot = 0;
    float sum2 = 0;
    float sum1 = 0;
    for (int i = 0; i < vec_1->cols; i++)
    {
        float n1 = vec_1->at<float>(0, i);
        float n2 = vec_2->at<float>(0, i);
        dot += n1*n2;            //向量内积求和
        sum2 += pow(n2, 2);
        sum1 += pow(n1, 2);
    }
    float norm = sqrt(sum2)*sqrt(sum1);  //两个向量到原点的距离相乘
    float similarity = dot / norm;
    float dis = acos(similarity) / CV_PI;
    return dis;
}
/*x
float CFaceRecognition::sumVec(Mat & vec)
{
    float sum = 0.0;
    for (int i = 0; i < vec.cols; i++)
        sum += vec.at<float>(0, i);
    return sum;
}

float CFaceRecognition::dotVec(cv::Mat & vec_1, cv::Mat & vec_2)
{
    float dot = 0.0;
    for (int i = 0; i < vec_1.cols; i++)
    {
        dot += vec_1.at<float>(0, i) * vec_2.at<float>(0, i);
    }
    return dot;
}

float CFaceRecognition::normVec(cv::Mat& vec_1, cv::Mat& vec_2)
{
    float sum1 = 0.0;
    float sum2 = 0.0;
    for (int i = 0; i < vec_1.cols; i++) 
    {
        sum1 += pow(vec_1.at<float>(0, i),2);
        sum2 += pow(vec_2.at<float>(0, i),2);
    }

    return sqrt(sum2)*sqrt(sum1);
}
*/

main.cpp

    CFaceRecognition fr(0.5);
    fr.train(cv::imread("0.jpg"), "yangxiqing");   //记录 128维度的人脸特征 
    fr.train(imread("1.jpg"), "yangxiqing");
    fr.train(imread("2.jpg"), "yangxiqing");
    fr.train(imread("3.jpg"), "yangxiqing");
    fr.train(imread("4.jpg"), "yangxiqing");
    fr.train(imread("5.jpg"), "yangxiqing");
    fr.train(imread("6.jpg"), "yangxiqing");
    fr.train(imread("7.jpg"), "yangxiqing");
    fr.train(imread("8.jpg"), "yangxiqing");
    fr.train(imread("9.jpg"), "yangxiqing");
    fr.train(imread("10.jpg"), "yangxiqing");
    while (true)
    {
        cap.read(src);            //读入摄像头数据
        if (!src.empty())
        {
            cout << "distance:" << fr.predict(src) << endl;        //判断人脸 并进行对比
            cv::imshow("output", src);            //显示人脸图像
            char s = waitKey(10);
            if (s == 'q')
                break;
        }
        else
        {
            std::cout << "read capture failed !" << std::endl;
            return -1;
        }
    }
    return 0;

}

 

 

猜你喜欢

转载自blog.csdn.net/weixin_45651122/article/details/105914876