windows下 opencv 图像 人脸检测 亲测可行

11 篇文章 2 订阅
8 篇文章 0 订阅

参考https://blog.csdn.net/li_wen01/article/details/78369751 


/*=============================================================================

#     FileName: facecheck.cpp

#         Desc: detect faces and eyes by opencv ,and then cut the face

#       Author: Licaibiao

#      Version:

#   LastChange: 2017-10-31

#      History:

=============================================================================*/

#include <opencv2/objdetect/objdetect.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <opencv2/imgproc/imgproc.hpp>

#include <iostream>

#include <stdio.h>



using namespace std;

using namespace cv;



#define CASCADENAME			"C:\\Users\\ThinkPad\\Downloads\\opencv\\sources\\data\\haarcascades_cuda\\haarcascade_frontalface_alt2.xml"

#define NESTEDCASCADENAME	"C:\\Users\\ThinkPad\\Downloads\\opencv\\sources\\data\\haarcascades_cuda\\haarcascade_eye_tree_eyeglasses.xml"

#define FACEPHOTO_FACENAME  "C:\\Users\\ThinkPad\\Pictures\\lena_detec.jpg"

#define DETECT_IMAGE		"C:\\Users\\ThinkPad\\Pictures\\lena.jpg"





void detectAndDraw(Mat& img, CascadeClassifier& cascade,

	CascadeClassifier& nestedCascade, double scale, bool tryflip)

{

	double t = 0;

	vector<Rect> faces, faces2;

	/* 定义七种颜色用于人脸标记 */

	const static Scalar colors[] =

	{

		Scalar(255,0,0),

		Scalar(255,128,0),

		Scalar(255,255,0),

		Scalar(0,255,0),

		Scalar(0,128,255),

		Scalar(0,255,255),

		Scalar(0,0,255),

		Scalar(255,0,255)

	};



	Mat gray, smallImg;



	/* 因为用的是类haar特征,所以都是基于灰度图像的,这里要转换成灰度图像 */

	cvtColor(img, gray, COLOR_BGR2GRAY);



	/* 将图片缩小,加快检测速度 */

	double fx = 1 / scale;

	/* 将尺寸缩小到1/scale, 用线性插值 */

	resize(gray, smallImg, Size(), fx, fx, INTER_LINEAR);

	/* 直方图均衡 */

	equalizeHist(smallImg, smallImg);



	/* 用来计算算法执行时间 */

	t = (double)getTickCount();



	/*人脸检测

		smallImg:输入的原图

		faces	:表示检测到的人脸目标序列

		1.1		:每次图像尺寸减小的比例为1.1

		2		:每一个目标至少要被检测到3次才算是真的目标

		CV_HAAR_SCALE_IMAGE:表示不是缩放分类器来检测,而是缩放图像

		Size(30, 30) 目标的最大最小尺寸

	*/

	cascade.detectMultiScale(smallImg, faces, 1.1, 2, CASCADE_SCALE_IMAGE, Size(30, 30));

	if (tryflip)

	{

		flip(smallImg, smallImg, 1);

		cascade.detectMultiScale(smallImg, faces2, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));

		for (vector<Rect>::const_iterator r = faces2.begin(); r != faces2.end(); ++r)

		{

			faces.push_back(Rect(smallImg.cols - r->x - r->width, r->y, r->width, r->height));

		}

	}



	/* 相减为算法执行的时间 */

	t = (double)getTickCount() - t;

	printf("detection time = %g ms\n", t * 1000 / getTickFrequency());



	for (size_t i = 0; i < faces.size(); i++)

	{

		Rect r = faces[i];

		Mat smallImgROI;

		vector<Rect> nestedObjects;

		Point center;

		Scalar color = colors[i % 8];

		int radius;



		/* 人脸长宽比例,在0.75-1.3 间画圆,其他范围画矩形 */

		double aspect_ratio = (double)r.width / r.height;

		if (0.75 < aspect_ratio && aspect_ratio < 1.3)

		{

			/*还原原来尺寸 计算圆心和圆半径 */

			center.x = cvRound((r.x + r.width*0.5)*scale);

			center.y = cvRound((r.y + r.height*0.5)*scale);

			radius = cvRound((r.width + r.height)*0.25*scale);

			/* 画出人脸检测区域 画圆 */

			circle(img, center, radius, color, 3, 8, 0);

		}

		else

		{

			/* 画出检测区域,画矩形 */

			rectangle(img, Point(cvRound(r.x*scale), cvRound(r.y*scale)),

				Point(cvRound((r.x + r.width - 1)*scale), cvRound((r.y + r.height - 1)*scale)), color, 3, 8, 0);

		}



		/* 检测到人眼,在人脸上画出人眼 */

		if (nestedCascade.empty())

		{

			continue;

		}



		smallImgROI = smallImg(r);



		/* 人眼检测 */

		nestedCascade.detectMultiScale(smallImgROI, nestedObjects, 1.1, 2, CASCADE_SCALE_IMAGE, Size(30, 30));

		for (size_t j = 0; j < nestedObjects.size(); j++)

		{

			Rect nr = nestedObjects[j];

			/*还原原来尺寸 计算圆心和圆半径 */

			center.x = cvRound((r.x + nr.x + nr.width*0.5)*scale);

			center.y = cvRound((r.y + nr.y + nr.height*0.5)*scale);

			radius = cvRound((nr.width + nr.height)*0.25*scale);

			/* 画出人眼检测区域 画圆*/

			circle(img, center, radius, color, 3, 8, 0);

		}

	}

	/* 显示图像 img */

	imshow("result", img);

}





int main(int argc, const char** argv)

{

	Mat frame, image;

	bool tryflip=0;

	CascadeClassifier cascade, nestedCascade;

	double scale = 1.3;



	/* 加载分类器 */

	if (!nestedCascade.load(NESTEDCASCADENAME))

	{

		cerr << "WARNING: Could not load classifier cascade for nested objects" << endl;

	}

	if (!cascade.load(CASCADENAME))

	{

		cerr << "ERROR: Could not load classifier cascade" << endl;

		return -1;

	}



	/* 加载图片 */

	image = imread(DETECT_IMAGE, 1);

	if (image.empty())

	{

		cout << "Couldn't read iamge" << DETECT_IMAGE << endl;



	}



	cout << "Detecting face(s) in " << DETECT_IMAGE << endl;



	/* 检测人脸及眼睛并画出检测到的区域 */

	if (!image.empty())

	{

		detectAndDraw(image, cascade, nestedCascade, scale, tryflip);

		waitKey(0);

	}

	return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值