#include<opencv2/highgui/highgui.hpp>
#include<opencv2/face.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/objdetect/objdetect.hpp>
#include<iostream>
#include<io.h>
//命名空间
using namespace std;
using namespace cv;
using namespace face;
CascadeClassifier faceDetect; //人脸检测对象
//函数声明
vector<Rect> FaceDetector(Mat img);//检测人脸,并返回人脸区域
void DrawFace(Mat img, vector<Rect> faces);//将人脸标注出来
void GetFilesName(string path, vector<string>& filesName);//获取文件夹里的所有文件名称
int main()
{
//变量
Mat frame;
Mat src;
Mat facePic;
Mat recogPic;
vector<Rect> faces;
vector<string> filesName;
string path = "..\\TrainPic";
string pic;
vector<Mat> trainPic;//训练图片
vector<int> labels;//与训练图片一一对应的标签
int result;
map<int, string> labelsInfo;
faceDetect.load("../models/haarcascade_frontalface_alt2.xml");
Ptr<FaceRecognizer> LBPHRecog = LBPHFaceRecognizer::create(1, 8, 3, 3, 50);//构造LBPH人脸识别类的对象并初始化
//加载人脸库
GetFilesName(path, filesName);
for (int i = 0; i < filesName.size(); i++)
{
pic = filesName[i];
src = imread(pic);
cvtColor(src, src, CV_RGB2GRAY);
trainPic.push_back(src);
labelsInfo.insert(make_pair(i, filesName[i]));
labels.push_back(i);
}
//LBPHRecog->setLabelsInfo(labelsInfo);
LBPHRecog->train(trainPic, labels); //LBP人脸识别训练函数
VideoCapture cap(0);//打开摄像头
int c = 0;
if (!cap.isOpened())
{
cerr << "摄像头无法打开" << endl;
}
while (c != 27)
{
cap >> frame;
flip(frame, frame, 1);
recogPic = Mat::zeros(200, 200, frame.type());
double t = (double)getTickCount();//检测的时间
faces = FaceDetector(frame);
t = ((double)getTickCount() - t) / getTickFrequency();
cout << t << endl;
DrawFace(frame, faces);
for (size_t i = 0; i < faces.size(); i++)
{
facePic = frame(Rect(faces[i]));
resize(facePic, recogPic, recogPic.size());
cvtColor(recogPic, recogPic, CV_RGB2GRAY);
//equalizeHist(recogPic, recogPic);
result = LBPHRecog->predict(recogPic);//进行识别
//将识别结果显示在实时画面上
if (result == -1)
putText(frame, "unknow", Point(faces[i].x, faces[i].y), 3, 0.5, Scalar(0, 255, 255), 1);
else
putText(frame, filesName[result], Point(faces[i].x, faces[i].y), 3, 0.5, Scalar(0, 255, 255), 1);
}
imshow("1", frame);
c = waitKey(1);
}
return 0;
}
vector<Rect> FaceDetector(Mat img)
{
Mat src = Mat::zeros(240, 320, img.type());
vector<Rect> faces;
cvtColor(img, img, CV_RGB2GRAY);
resize(img, src, src.size());
faceDetect.detectMultiScale(src, faces, 1.2, 6, 0, Size(30, 30));
for (int i = 0; i < faces.size(); i++)
{
faces[i].x = faces[i].x * 2;
faces[i].y = faces[i].y * 2;
faces[i].width = faces[i].width * 2;
faces[i].height = faces[i].height * 2;
}
return faces;
}
void DrawFace(Mat img, vector<Rect> faces)
{
for (size_t num = 0; num < faces.size(); num++)
{
rectangle(img, Point(faces[num].x, faces[num].y),
Point(faces[num].x + faces[num].width, faces[num].y + faces[num].height), Scalar(0, 255, 0), 1, 8);
}
}
void GetFilesName(string path, vector<string>& filesName)
{
//文件句柄
long hFile = 0;
//文件信息
struct _finddata_t fileinfo;
string p;
if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
{
do
{
//如果是目录,迭代之
//如果不是,加入列表
if ((fileinfo.attrib & _A_SUBDIR))
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
GetFilesName(p.assign(path).append("\\").append(fileinfo.name), filesName);
}
else
{
filesName.push_back(p.assign(path).append("\\").append(fileinfo.name));
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}