基于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;

}

经验分享 程序员 微信小程序 职场和发展