MFC实现opencv人脸检测 上一篇:opencv人脸检测_cascade.detectMultiScale参数详解

上一篇:opencv人脸检测_cascade.detectMultiScale参数详解

不知道有没有帮助到大家,如果没有肯定是我没有讲的太清楚,那么我修改了下上篇,手把手写一下。

本篇是用MFC进界面编写,遇到些问题,很难受。

1.关于MFC

     微软基础类库(英语:Microsoft Foundation Classes,简称MFC)是一个微软公司提供的类库(class libraries),以C++类的形式封装了Windows API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含的类包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。

2.常用控件

Button

Picture Control

Static Text

Radio Butto

3.程序实现

 其实我要实现的是打开文件中的人物图片且显示,然后点击检测图片后显示圈出人脸的图片再左边。


OpenImg控件的实现没有问题,如下。


代码如下:

void CfacedectectMFC2Dlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	//进度条置为零
	//CProgressCtrl  *prgs = (CProgressCtrl *)GetDlgItem(IDC_PROGRESS);
	//prgs->SetPos(0);
	//选择图片
	CFileDialog fileDlg(TRUE, _T("png"), NULL, 0, _T("image Files(*.bmp; *.jpg;*.png)|*.JPG;*.PNG;*.BMP|All Files (*.*) |*.*||"), this);
	fileDlg.DoModal();
	//获取图片路径和图片名称
	 CString strFilePath = fileDlg.GetPathName();
	/* printf("%s", strFilePath);*/
	 CString strFileName = fileDlg.GetFileName();
	//判断路径不为空
	if (strFilePath == _T(""))
	{
		return;
	}
	ATL::CImage image;
	image.Load(strFilePath);
	image.Save(_T("open.jpg"));
	//以下两个矩形主要作用是,获取对话框上面的Picture Control的width和height,
	//并设置到图片矩形rectPicture,根据图片矩形rectPicture对图片进行处理,
	//最后绘制图片到对话框上Picture Control上面
	CRect rectControl;                        //控件矩形对象
	CRect rectPicture;                        //图片矩形对象

	int x = image.GetWidth();
	int y = image.GetHeight();
	//Picture Control的ID为IDC_open
	CWnd  *pWnd = GetDlgItem(IDC_open2);
	pWnd->GetClientRect(rectControl);


	CDC *pDc = GetDlgItem(IDC_open2)->GetDC();
	SetStretchBltMode(pDc->m_hDC, STRETCH_HALFTONE);

	rectPicture = CRect(rectControl.TopLeft(), CSize((int)rectControl.Width(), (int)rectControl.Height()));

	((CStatic*)GetDlgItem(IDC_open2))->SetBitmap(NULL);

	//以下两种方法都可绘制图片
	//image.StretchBlt(pDc->m_hDC, rectPicture, SRCCOPY); //将图片绘制到Picture控件表示的矩形区域
	image.Draw(pDc->m_hDC, rectPicture);                //将图片绘制到Picture控件表示的矩形区域

	image.Destroy();
	pWnd->ReleaseDC(pDc);
}

是的,你想的没错,我就是用找到的图片利用  image.Save(_T("open.jpg")); 保存到本项目文件下,以便DetectImg控件去使用读入的图片。

其实我知道有点不好,但是我现在目前没有找到资料去定义全局变量,也就是将OpenImg控件读入的图片设置为全局变量Mat ,这样就可以给DetectImg控件使用了,然后检测人脸,然后而且可以直接在原图上圈出人脸,然后显示在右边窗口。


哎。。难受呀,没有找到资料,我还是第一次学习MFC,这算是第一个项目工程,MFC显示图片到窗口有很多种办法,三种吧,我可能用的是最古老的那种方法,所以还可以好好学习一下,应该是没有问题的。


void CfacedectectMFC2Dlg::OnBnClickedButton2()
{
	// TODO: 在此添加控件通知处理程序代码
	/////////////////////////////////////             
	//// 这一段用于检测人脸,后期可  ////
	//// 自定义子函数,增加程序可读性 ////
	/////////////////////////////////////
	//1.加载分类器
	CascadeClassifier cascade;
	cascade.load("haarcascade_frontalface_alt2.xml");
	//	cascade.load("haarcascade_frontalface_default.xml");
	Mat srcImg, dstImg, grayImg;
	CString strFilePath;
	//2.读取图片
	srcImg = imread("open.jpg");
	dstImg = srcImg.clone();
	grayImg.create(srcImg.size(), srcImg.type());
	cvtColor(srcImg, grayImg, CV_BGR2GRAY);//生成灰度图,提高检测效率

										   //定义7种颜色,用于标记人脸
	Scalar colors[] =
	{
		//红橙黄绿青蓝紫  
		CV_RGB(255, 0, 0),
		CV_RGB(255, 97, 0),
		CV_RGB(255, 255, 0),
		CV_RGB(0, 255, 0),
		CV_RGB(0, 255, 255),
		CV_RGB(0, 0, 255),
		CV_RGB(160, 32, 240)
	};


	//3.检测
	vector<Rect> rect;
	cascade.detectMultiScale(grayImg, rect, 1.1, 3, 0);//分类器对象调用

													   //	printf("检测到人脸个数:%d\n", rect.size());

													   //4.标记--在脸部画圆
	for (int i = 0; i < rect.size(); i++)
	{
		Point center;
		int radius;
		center.x = cvRound((rect[i].x + rect[i].width * 0.5));
		center.y = cvRound((rect[i].y + rect[i].height * 0.5));

		radius = cvRound((rect[i].width + rect[i].height) * 0.25);
		circle(dstImg, center, radius, colors[i % 7], 2);
	}
	imwrite("after.jpg", dstImg);

	int cx, cy;
	ATL::CImage  dstimage;
	CRect   rect1;
	dstimage.Load(_T("after.jpg"));

	//获取图片的宽 高  
	cx = dstimage.GetWidth();
	cy = dstimage.GetHeight();

	CWnd *pWnd = NULL;
	pWnd = GetDlgItem(IDCLOSE);//获取控件句柄  
							   //获取Picture Control控件的客户区  
	pWnd->GetClientRect(&rect1);

	CDC *pDc = NULL;
	pDc = pWnd->GetDC();//获取picture control的DC    
						//设置指定设备环境中的位图拉伸模式  
	int ModeOld = SetStretchBltMode(pDc->m_hDC, STRETCH_HALFTONE);
	//从源矩形中复制一个位图到目标矩形,按目标设备设置的模式进行图像的拉伸或压缩  
	dstimage.StretchBlt(pDc->m_hDC, rect1, SRCCOPY);
	SetStretchBltMode(pDc->m_hDC, ModeOld);
	ReleaseDC(pDc);





	/*IplImage iplimg = dstImg;*/
	//DrawPicToHDC(&iplimg, IDCLOSE);
}

这里出现问题......

我想很快就可以解决了。。。。。

猜你喜欢

转载自blog.csdn.net/qq_37791134/article/details/80592025