上一篇: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更新图像时,旧位置的图像怎么清除?