在MFC工程中划定感兴趣区域,以便于在划定区域中进行行人检测。
感兴趣区域(ROI,region of interest)
机器视觉、图像处理中,从被处理的图像以方框、圆、椭圆、不规则多边形等方式勾勒出需要处理的区域,称为感兴趣区域,ROI。
在Halcon、OpenCV、Matlab等机器视觉软件上常用到各种算子(Operator)和函数来求得感兴趣区域ROI,并进行图像的下一步处理。 在图像处理领域,感兴趣区域(ROI) 是从图像中选择的一个图像区域,这个区域是你的图像分析所关注的重点。圈定该区域以便进行进一步处理。使用ROI圈定你想读的目标,可以减少处理时间,增加精度。
MFC工程下划定感兴趣区域
划定区域的关键是获得感兴趣区域的坐标,首先获取第一帧图片进行坐标的选取,划定后进行视频的显示。
划定ROI区域中项目中,回调函数等参数介绍可以了解OpenCV中感兴趣区域的选取与检测(一)
- 创建MFC基于对话框工程文件,添加相应控件
- 打开视频文件区域关键代码如下,获取一帧进行显示
void CROIDlg::OnBnClickedOpen() { CFileDialog dlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY, NULL, NULL); // 选项图片的约定 dlg.m_ofn.lpstrTitle = _T("打开视频文件"); // 打开文件对话框的标题名 if (dlg.DoModal() != IDOK) // 判断是否获得图片 return; flageS = true; CString mPath = dlg.GetPathName(); FileName = mPath;// 获取图片路径 if (capture.isOpened()) { capture.release(); } if (!capture.open(LPCSTR(mPath))) { MessageBox("打开视频出错!"); return; } else { Mat src; capture >> src; IplImage* m_Frame; m_Frame = &IplImage(src); CvvImage m_CvvImage; m_CvvImage.CopyOf(m_Frame, 1); m_CvvImage.DrawToHDC(hDC, &rect); //通过句柄hDC,显示 } }
- 划定ROI区域相关代码如下,
void CROIDlg::OnBnClickedRoi() { // TODO: 在此添加控件通知处理程序代码 //视频中的第一帧 Mat firstFrame; Mat src; flageROI = true; capture >> src; //复制到firstFrame中 src.copyTo(firstFrame); //register namedWindow("ROI", WINDOW_AUTOSIZE); /*resizeWindow("ROI", 600, 500);*/ setMouseCallback("ROI", mouseRectHandler, NULL); //画感兴趣区域 while (!gotBox) { firstFrame.copyTo(src); rectangle(src, box, Scalar(255, 0, 0), 2);//画出感兴趣区域 imshow("ROI", src); if (waitKey(50) == 'q') break; } //remove callback setMouseCallback("ROI", NULL, NULL); destroyWindow("ROI"); flageROI = true; if (flageROI) { // 显示图像参数 capture >> sour; flageS = true; char chEdit[10]; _itoa_s(sour.cols, chEdit, 10); SetDlgItemText(IDC_SHOW, chEdit); _itoa_s(sour.rows, chEdit, 10); SetDlgItemText(IDC_SHOW, chEdit); // 刷新显示区 Invalidate(TRUE); // 设置定时器 SetTimer(1, 40, NULL); } }
- 回调函数
mouseRectHandler
为void mouseRectHandler(int event, int x, int y, int flags, void *param) { //Mat img = src.clone(); switch (event) { case CV_EVENT_MOUSEMOVE: if (drawing_box) { //鼠标的移动到downPoint的右下角 if (x >= downPoint.x && y >= downPoint.y) { box.x = downPoint.x; box.y = downPoint.y; box.width = x - downPoint.x; box.height = y - downPoint.y; } //鼠标的移动到downPoint的右上角 if (x >= downPoint.x && y <= downPoint.y) { box.x = downPoint.x; box.y = y; box.width = x - downPoint.x; box.height = downPoint.y - y; } //鼠标的移动到downPoint的左上角 if (x <= downPoint.x && y <= downPoint.y) { box.x = x; box.y = y; box.width = downPoint.x - x; box.height = downPoint.y - y; } //鼠标的移动到downPoint的左下角 if (x <= downPoint.x && y >= downPoint.y) { box.x = x; box.y = downPoint.y; box.width = downPoint.x - x; box.height = y - downPoint.y; } } break; case CV_EVENT_LBUTTONDOWN: //按下鼠标,代表可以可以开始画矩形 drawing_box = true; //记录起点 downPoint = Point(x, y); //初始化起始矩形框 box = Rect(x, y, 0, 0); break; case CV_EVENT_LBUTTONUP: //松开鼠标,代表结束画矩形 drawing_box = false; gotBox = true; break; default: break; } }
- 回调函数
- 效果图: