OpenCv中已经有训练好的人脸数据集,所以我们直接就可以拿过来进行检测。还有一些其余的训练好的数据:
具体路径:D:\OpenCv-3.4.1\opencv\build\etc\haarcascades
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
//读进来训练的人脸检测文件
String fileName = "D:/OpenCv-3.4.1/opencv/build/etc/haarcascades/haarcascade_frontalface_alt.xml";
CascadeClassifier casca_classifier;
/*---------图片人脸检测------------*/
int main(int argc, char ** argv)
{
if (!casca_classifier.load(fileName))
{
cout << "人脸训练数据未找到!" << endl;
return -1;
}
Mat src = imread("D:/test/girl.png");
Mat gray_src;
if (src.empty())
{
cout << "待检测图片未找到!" << endl;
return -1;
}
cvtColor(src, gray_src, CV_BGR2GRAY);
equalizeHist(gray_src, gray_src);//直方图均衡化
vector<Rect> rect;
//分类器在不同的人脸尺度空间上计算并将结果返回到rect矩形数组中
casca_classifier.detectMultiScale(gray_src, rect, 1.1, 3, 0, Size(25, 25));
for (size_t t = 0; t < rect.size(); t++)
{
rectangle(src, rect[static_cast<int>(t)], Scalar(0, 0, 255), 2, 8, 0);
}
imshow("face detect result", src);
waitKey(0);
return 0;
}
运行结果:
换一张图片:
可以看到,效果还是不错的,至少全部检测出来了。
我们也可以检测人的眼部位置,OpenCv中也有训练好的眼部数据集,只不过精度不是很高,现在我们在原来的代码上增加几条代码,源代码如下:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
//读进来训练的人脸检测文件
String facefileName = "D:/OpenCv-3.4.1/opencv/build/etc/haarcascades/haarcascade_frontalface_alt.xml";
//读进来训练的眼部检测文件
String eyefileName = "D:/OpenCv-3.4.1/opencv/build/etc/haarcascades/haarcascade_eye.xml";
CascadeClassifier face_classifier,eye_classifier;
/*---------图片人脸检测------------*/
int main(int argc, char ** argv)
{
if (!face_classifier.load(facefileName))
{
cout << "人脸训练数据未找到!" << endl;
return -1;
}
if (!eye_classifier.load(eyefileName))
{
cout << "眼部训练数据未找到!" << endl;
return -1;
}
Mat src = imread("D:/test/girl.png");
Mat gray_src;
if (src.empty())
{
cout << "待检测图片未找到!" << endl;
return -1;
}
cvtColor(src, gray_src, CV_BGR2GRAY);
equalizeHist(gray_src, gray_src);//直方图均衡化
vector<Rect> rect;
//分类器在不同的人脸尺度空间上计算并将结果返回到rect矩形数组中
face_classifier.detectMultiScale(gray_src, rect, 1.1, 3, 0, Size(20, 20));
vector<Rect>eyes;
for (size_t t = 0; t < rect.size(); t++)
{ //分类器在不同的眼部尺度空间上计算并将结果返回到rect矩形数组中
eye_classifier.detectMultiScale(gray_src, eyes, 1.1, 3, 0, Size(15, 15));
for (size_t i = 0; i < eyes.size(); i++)
{
rectangle(src, eyes[static_cast<int>(i)], Scalar(0, 255, 0), 2, 8, 0);
}
rectangle(src, rect[static_cast<int>(t)], Scalar(0, 0, 255), 2, 8, 0);
}
imshow("face detect result", src);
waitKey(0);
return 0;
}
运行结果:
但是,对于一张很多人的图片来说,要检测眼部位置确实不容易,比如:
这样一张比较模糊且眼部遮挡的图就无法全部检测到。