一、利用卷积神经网络进行人脸检测,称作CFF(卷积人脸搜索)
卷积神经网络人脸识别的大致流程:
1)对本地人脸进行特征提取
2)打开摄像头(opencv)
3)从cap获取信息
4)找人脸
5)对人脸进行特征提取
6)与已经存储的特征进行比对
7)如果余弦夹角相近,使得余弦值大于阈值,则判断成功。
二、卷积神经网络人脸识别(C++实现):
FaceRecognition.h
#pragma once
#include
#include
#include
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
std::vector
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 n2 = vec_2->at
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
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
}
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
sum2 += pow(vec_2.at
}
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;
}