利用opencv库函数检测人脸、眼睛以及鼻子等区域

时间:2022-06-18 12:35:58
//  Haar特征-人脸检测  //

#include<opencv2/opencv.hpp>
#include<cstdio>
#include<cstdlib>
#include<Windows.h>
using namespace std;
using namespace cv;


int flag=0;
CvPoint pt1,pt2;

int main(int argc, int argv[])
{
	// 加载Haar特征检测分类器 
	// haarcascade_frontalface_alt.xml系OpenCV自带的分类器 下面是机器上的文件路径
	const char *pstrCascadeFileName="E:\\opencv软件\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml";
	CvHaarClassifierCascade *pHaarCascade=NULL;
	pHaarCascade=(CvHaarClassifierCascade*)cvLoad(pstrCascadeFileName);

	const char *pstrCascadeEyeName="E:\\opencv软件\\opencv\\sources\\data\\haarcascades\\haarcascade_eye_tree_eyeglasses.xml";
	CvHaarClassifierCascade *pHaarCascadeEye=NULL;
	pHaarCascadeEye=(CvHaarClassifierCascade*)cvLoad(pstrCascadeEyeName);  //人眼分类器

	const char *pstrCascadeNoseName="E:\\opencv软件\\opencv\\sources\\data\\haarcascades\\haarcascade_mcs_nose.xml";
	CvHaarClassifierCascade *pHaarCascadeNose=NULL;
	pHaarCascadeNose=(CvHaarClassifierCascade*)cvLoad(pstrCascadeNoseName);  //鼻子分类器

	const char *pstrCascadeMouthName="E:\\opencv软件\\opencv\\sources\\data\\haarcascades\\haarcascade_mcs_mouth.xml";
	CvHaarClassifierCascade *pHaarCascadeMouth=NULL;
	pHaarCascadeMouth=(CvHaarClassifierCascade*)cvLoad(pstrCascadeMouthName);  //嘴巴分类器

	// 载入图像
	const char *pstrImageName="F:\\Opencv测试图片\\ZhouXun.jpg";
	IplImage*pSrcImage=cvLoadImage(pstrImageName,CV_LOAD_IMAGE_UNCHANGED);

	IplImage *pGrayImage=cvCreateImage(cvGetSize(pSrcImage),IPL_DEPTH_8U,1);
	cvCvtColor(pSrcImage,pGrayImage,CV_BGR2GRAY);
	IplImage *pDestImage =NULL;
	IplImage *pLeftImage =NULL;
	IplImage *pRightImage =NULL;
	CvRect Rect1,Rect2;
	IplImage *pImage1 =NULL;
	IplImage *pImage2 =NULL;

	cvNamedWindow("人脸识别",CV_WINDOW_AUTOSIZE);

	// 人脸识别与标记 
	if(pHaarCascade !=NULL)
	{
		CvScalar FaceCirclecolors[]=
		{
			{{0,0,255}},
			{{0,128,255}},
			{{0,255,255}},
			{{0,255,0}},
			{{255,128,0}},
			{{255,255,0}},
			{{255,0,0}},
			{{255,0,255}},
		};
		CvMemStorage *pcvMStorage =cvCreateMemStorage(0);
		cvClearMemStorage(pcvMStorage);

		// 识别
		CvSeq *pcvSeqFaces =cvHaarDetectObjects(pGrayImage,pHaarCascade,pcvMStorage);	

		// 标记
		for(int i=0;i<pcvSeqFaces->total;i++)
		{
			CvRect *r=(CvRect*)cvGetSeqElem(pcvSeqFaces,1);

			pt1.x =r->x;
			pt1.y =r->y;
			pt2.x =r->x + r->width;
			pt2.y =r->y + r->height;
			cvRectangle(pSrcImage,pt1,pt2,CV_RGB(255,0,0),2);   //用矩形区域标 记人脸

			Rect1 =cvRect(pt1.x,pt1.y,r->width,r->height);
			Rect2 =cvRect(pt1.x+(pt2.x-pt1.x)/4,pt1.y+(pt2.y-pt1.y)*1/3,r->width/2,r->height*2/3);

			CvSize size1 =cvSize(r->width,r->height);
			pImage1 =cvCreateImage(size1,pSrcImage->depth,pSrcImage->nChannels);
			cvSetImageROI(pSrcImage,Rect1);  //将人脸部分设置成ROI区域
			cvCopy(pSrcImage,pImage1);  //提取人脸部分
			cvResetImageROI(pSrcImage);

			CvSize size2 =cvSize(r->width/2,r->height*2/3);
			pImage2 =cvCreateImage(size2,pSrcImage->depth,pSrcImage->nChannels);
			cvSetImageROI(pSrcImage,Rect2);  //将鼻子部分设置成ROI区域
			cvCopy(pSrcImage,pImage2);  //提取鼻子ROI区域
			cvResetImageROI(pSrcImage);

			//cvSaveImage("F:\\Opencv测试图片\\Mouth31.jpg",pImage2);
			flag=1;
		}
		cvReleaseMemStorage(&pcvMStorage);

	}
	
	if(flag==1)
	{
		
			 //人眼识别与标记
			if(pHaarCascadeEye!=NULL)
			{
				CvScalar EyeCirclecolors[]=
				{
					{{0,0,255}},
					{{0,128,255}},
					{{0,255,255}},
					{{0,255,0}},
					{{255,128,0}},
					{{255,255,0}},
					{{255,0,0}},
					{{255,0,255}},
				};
				CvMemStorage *pcvMStorage1 =cvCreateMemStorage(0); //用来存储检测到的一序列候选目标矩形框的内存区域,内存存储器,存储块大小默认为64K
				cvClearMemStorage(pcvMStorage1);   //清空内存存储块,不释放内存,将存储块的top置到存储块的头部
				CvSeq *pcvSeqEyes =cvHaarDetectObjects(pImage1,pHaarCascadeEye,pcvMStorage1);   //人眼检测函数,
			
				for(int i=0;i<pcvSeqEyes->total;i++)
				{
					
					CvRect *p=(CvRect*)cvGetSeqElem(pcvSeqEyes,i);  //获取第i个人眼序列区域,将其强制转换成矩形结构
					CvPoint pt3,pt4;
					pt3.x =p->x;
			        pt3.y =p->y;
			        pt4.x =p->x + p->width;
			        pt4.y =p->y + p->height;
			        cvRectangle(pSrcImage,cvPoint(pt3.x+pt1.x,pt3.y+pt1.y),cvPoint(pt4.x+pt1.x,pt4.y+pt1.y),CV_RGB(0,255,0),2);   //用矩形区域标记人眼
				}			
				cvReleaseMemStorage(&pcvMStorage1);   //释放创建的内存块
			}		
	}


	if(flag==1)
	{
		
			 //鼻子识别与标记
			if(pHaarCascadeNose!=NULL)
			{
				CvMemStorage *pcvMStorage1 =cvCreateMemStorage(0); //用来存储检测到的一序列候选目标矩形框的内存区域,内存存储器,存储块大小默认为64K
				cvClearMemStorage(pcvMStorage1);   //清空内存存储块,不释放内存,将存储块的top置到存储块的头部
				CvSeq *pcvSeqEyes =cvHaarDetectObjects(pImage2,pHaarCascadeNose,pcvMStorage1);   //鼻子检测函数,
			
				for(int i=0;i<pcvSeqEyes->total;i++)
				{
					CvRect *p=(CvRect*)cvGetSeqElem(pcvSeqEyes,i);  //获取第i个鼻子序列区域,将其强制转换成矩形结构
					CvPoint pt5,pt6;
					pt5.x =p->x;
			        pt5.y =p->y;
			        pt6.x =p->x + p->width;
			        pt6.y =p->y + p->height;
			        cvRectangle(pSrcImage,cvPoint(pt5.x+Rect2.x,pt5.y+Rect2.y),cvPoint(pt6.x+Rect2.x,pt6.y+Rect2.y),CV_RGB(255,0,0),2);   //用矩形区域标记鼻子			
				}			
				cvReleaseMemStorage(&pcvMStorage1);   //释放创建的内存块
			}		
	}

	cvSaveImage("F:\\Opencv测试图片\\ZhouXun1.jpg",pSrcImage);

	cvShowImage("人脸识别",pSrcImage);
	cvWaitKey(0);

	cvDestroyWindow("人脸识别");
	cvReleaseImage(&pSrcImage);
	cvReleaseImage(&pGrayImage);
	return 0;
}
利用opencv库函数检测人脸、眼睛以及鼻子等区域