MFC实现opencv人脸检测(优化版)

上一篇:MFC实现opencv人脸检测。

没有解决的问题:用找到的图片利用  image.Save(_T("open.jpg")); 保存到本项目文件下,以便DetectImg控件去使用读入的图片。其实我知道有点不好,但是我现在目前没有找到资料去定义全局变量,也就是将OpenImg控件读入的图片设置为全局变量Mat ,这样就可以给DetectImg控件使用了,然后检测人脸,然后而且可以直接在原图上圈出人脸,然后显示在右边窗口。

这次问题解决了。

故意找了一张很垃圾像素的照片来测试,效果还是很理想的,所以可以用,欢迎学习。

代码如下:

void CfacedectectMFC3Dlg::OnBnClickedReading()
{
	CStatic* pStatic = (CStatic*)GetDlgItem(IDC_reading);
	/*CRect lRect;
	pStatic->GetClientRect(&lRect);
	pStatic->GetDC()->FillSolidRect(lRect.left, lRect.top, lRect.Width(), lRect.Height(), RGB(240, 240, 240));*/
	pStatic->SetBitmap(NULL);

	CFileDialog dlg(TRUE, _T(".jpg"), _T(""), OFN_OVERWRITEPROMPT, _T("JPG File(*.jpg)|*.jpg|"));
	if (dlg.DoModal() == IDOK)
	{
		CString sFilePath = dlg.GetPathName();
		string filepath = CT2A(sFilePath);
		readimage = imread(filepath, 1);
		if (!readimage.empty())
		{
	
			CRect rect;
			GetDlgItem(IDC_reading)->GetClientRect(rect);
			cv::namedWindow("myshowWnd", WINDOW_NORMAL);
			cv::resizeWindow("myshowWnd", rect.Width(), rect.Height());

			HWND hWnd = (HWND)cvGetWindowHandle("myshowWnd");
			HWND hParent = ::GetParent(hWnd);
			::SetParent(hWnd, GetDlgItem(IDC_reading)->m_hWnd);
			::ShowWindow(hParent, SW_HIDE);

			imshow("myshowWnd", readimage);
			imshow("readimage", readimage);
		}
		else
		{
			MessageBox(_T("JPG file is empty"));
			return;
		}
	}
	
	waitKey(10);
}

// TODO: 在此添加控件通知处理程序代码
	/////////////////////////////////////             
	//// 这一段用于检测人脸,后期可  ////
	//// 自定义子函数,增加程序可读性 ////
	/////////////////////////////////////
	//1.加载分类器
	CascadeClassifier cascade;
	cascade.load("haarcascade_frontalface_alt2.xml");
	//	cascade.load("haarcascade_frontalface_default.xml");
	Mat dstImg, grayImg;
	CString strFilePath;
	//2.读取图片
	dstImg = readimage.clone();
	grayImg.create(readimage.size(), readimage.type());
	cvtColor(readimage, 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);

	CRect rect1;
	GetDlgItem(IDC_detect)->GetClientRect(rect1);
	cv::namedWindow("mydetect", WINDOW_NORMAL);
	cv::resizeWindow("mydetect", rect1.Width(), rect1.Height());

	HWND hWnd = (HWND)cvGetWindowHandle("mydetect");
	HWND hParent = ::GetParent(hWnd);
	::SetParent(hWnd, GetDlgItem(IDC_detect)->m_hWnd);
	::ShowWindow(hParent, SW_HIDE);

	imshow("mydetecty", dstImg);
	imshow("mydetect", dstImg);

全部工程代码如下链接下载:

https://download.csdn.net/download/qq_37791134/10463611

上面的代码已经很完美了,但是我觉得还不够完美,就是:MFC更新图像时,旧位置的图像怎么清除?


猜你喜欢

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