OpenCV基于haar分类器算法的人脸检测实现(一)

近期要开展一个新项目,关于场景图像信息获取的,具体涉及到场景中人脸检测、运动目标检测以及场景中给定目标的追踪问题,后面还会涉及到信息交互的界面开发。接下来将通过写博客的方式记录项目进展(问题及解决方案)和心得。

人脸检测

人脸检测不同于人脸识别,人脸检测通俗的意思就是在获取是场景数据(图像、视频)中,将具有人脸特征的目标检测出来,但不清楚检测到的人脸是谁,只知道这可能是一张脸;人脸识别就是在检测的基础上,能够对检测到的人脸进行辨识,进而知道这个人是“张三”还是“李四”或是“鸣人”还是“佐助”。

人脸检测/识别基本步骤

1.图像采集
静态图片、视频文件、摄像头、流媒体
2.图像预处理
简化图像、滤波、灰度化、二值化
3.特征提取
HAAR、HOGLBP…
4.匹配识别
分类对比

OpenCV识别代码

人脸检测通过调用OpenCV训练的人脸模型xml文件以及调用对应的库函数,即可实现不错的检测效果。

//#include 
//#include 
#include 
#include 
#include 
#include 

#include "opencv2\core\core.hpp"
#include "opencv2\imgproc\imgproc.hpp"
#include"opencv2\highgui\highgui.hpp"
#include "opencv2\objdetect\objdetect.hpp"

#include
#include

#include
#include 
#include


using namespace std;
using namespace cv;
void DetectFace(Mat, Mat);
CascadeClassifier faceCascade;
CascadeClassifier face_profile_Cascade;
CascadeClassifier eyes_Cascade;
int main(int argc, char** argv) {
	VideoCapture cap(0);
	//if (!cap.open("C:\\Users\\Desktop\\faceDetect-master\\faceDetect-master\\meinv.mp4")) {
	//	cout << "摄像头打开失败!!" << endl;	
	//	return -1;
	//}

	if (!cap.isOpened())  // if not success, exit program
	{
		cout << "Cannot open the video cam" << endl;
		return -1;
	}


	//D:\\openCV410\\opencv\\sources\\data\\haarcascades_cuda\\haarcascade_profileface.xml  
	//haarcascade_frontalface_alt2
	//haarcascade_profileface
	//D:\\openCV410\\opencv\\sources\\data\\haarcascades_cuda\\haarcascade_frontalface_alt2.xml
	//D:\\openCV410\\opencv\\sources\\data\\haarcascades\\haarcascade_profileface.xml
	//D:\\openCV410\\opencv\\build\\etc\\haarcascades\\haarcascade_profileface.xml

	if (!faceCascade.load("D:\\openCV410\\opencv\\sources\\data\\haarcascades_cuda\\haarcascade_frontalface_alt2.xml")) {
		cout << "人脸检测级联分类器没找到!!" << endl;
		return -1;
	}

	if (!face_profile_Cascade.load("D:\\openCV410\\opencv\\sources\\data\\haarcascades\\haarcascade_profileface.xml")) {
		cout << "人脸检测级联分类器没找到!!" << endl;
		return -1;
	}

	if (!eyes_Cascade.load("D:\\openCV410\\opencv\\sources\\data\\haarcascades_cuda\\haarcascade_eye_tree_eyeglasses.xml")) {
		cout << "眼睛检测级联分类器没找到!!" << endl;
		return -1;
	}

	Mat img, imgGray;
	int fps = 60;
	while (true) {
		cap >> img;
		cvtColor(img, imgGray, CV_BGR2GRAY);
		equalizeHist(imgGray, imgGray);//直方图均匀化
		DetectFace(img, imgGray);
		waitKey(1000 / fps);
	}
	return 0;
}

void DetectFace(Mat img, Mat imgGray) {
	namedWindow("src", WINDOW_AUTOSIZE);
	vector<Rect> faces,profilefaces,eyes;
	faceCascade.detectMultiScale(imgGray, faces, 1.2, 5, 0, Size(30, 30));
	for (auto b : faces) {
		cout << "输出一张正面人脸位置:(x,y):" << "(" << b.x << "," << b.y << ") , (width,height):(" << b.width << "," << b.height << ")" << endl;
	}
	if (faces.size() > 0) {
		for (size_t i = 0; i < faces.size(); i++) {
			putText(img, "find_front!", cvPoint(faces[i].x, faces[i].y - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 0, 255));

			//画矩形框,给定矩形框左上角的一个点,设定宽和高,最终确定矩形框的范围
			rectangle(img, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), Scalar(0, 0, 255), 1, 8);
			cout << faces[i] << endl;
			//将人脸从灰度图中抠出来
			Mat face_ = imgGray(faces[i]);
			//eyes_Cascade.detectMultiScale(face_, eyes, 1.2, 2, 0, Size(30, 30));
			//for (size_t j = 0; j < eyes.size(); j++) {
			//	Point eye_center(faces[i].x + eyes[j].x + eyes[j].width / 2, faces[i].y + eyes[j].y + eyes[j].height / 2);
			//	int radius = cvRound((eyes[j].width + eyes[j].height)*0.25);
			//	circle(img, eye_center, radius, Scalar(65, 105, 255), 4, 8, 0);
			//}
		}
	}
	//侧脸
	face_profile_Cascade.detectMultiScale(imgGray, profilefaces, 1.2, 5, 0, Size(30, 30));
	for (auto b : profilefaces) {
		cout << "输出一张侧面人脸位置:(x,y):" << "(" << b.x << "," << b.y << ") , (width,height):(" << b.width << "," << b.height << ")" << endl;
	}
	if (profilefaces.size() > 0) {
		for (size_t i = 0; i < profilefaces.size(); i++) {
			putText(img, "find_profile!", cvPoint(profilefaces[i].x, profilefaces[i].y - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(255, 0, 0));

			rectangle(img, Point(profilefaces[i].x, profilefaces[i].y), Point(profilefaces[i].x + profilefaces[i].width, profilefaces[i].y + profilefaces[i].height), Scalar(255, 0, 0), 1, 8);
			cout << profilefaces[i] << endl;
			//将人脸从灰度图中抠出来
			Mat face_ = imgGray(profilefaces[i]);
			//eyes_Cascade.detectMultiScale(face_, eyes, 1.2, 2, 0, Size(30, 30));
			//for (size_t j = 0; j < eyes.size(); j++) {
			//	Point eye_center(profilefaces[i].x + eyes[j].x + eyes[j].width / 2, profilefaces[i].y + eyes[j].y + eyes[j].height / 2);
			//	int radius = cvRound((eyes[j].width + eyes[j].height)*0.25);
			//	circle(img, eye_center, radius, Scalar(65, 105, 255), 4, 8, 0);
			//}
		}
	}

	imshow("src", img);
}

haarcascade_frontalface_alt2.xml 正脸检测训练文件
haarcascade_profileface.xml 侧脸检测训练文件

类似于以上训练文件,在安装OpenCV时,就已经配置到安装目录下的某个位置。我们在使用时,直接去调用对应目录下的文件即可。需要注意的是,文件最好使用OpenCV安装目录下的文件,不要自行下载相应的xml文件,然后再去调用下载后的文件目录下的文件,这样保证不会出现文件版本不一造成加载错误。

检测效果

正面检测:
OpenCV基于haar分类器算法的人脸检测实现(一)_第1张图片
侧脸检测:
OpenCV基于haar分类器算法的人脸检测实现(一)_第2张图片
在Opencv自带了很多中对应目标的训练文件,如下图所示,根据自己的检测需求,添加相应的文件及检测代码即可完成目标检测。
OpenCV基于haar分类器算法的人脸检测实现(一)_第3张图片
~~感谢阅读

你可能感兴趣的:(OpenCV,计算机视觉,opencv,人脸识别)