【OpenCV+MFC】之一:在Picture控件显示图像

来源:互联网 发布:15年广东省的经济数据 编辑:程序博客网 时间:2024/05/01 10:24

前几天发了一个文章,是MFC控件上显示BMP图片,没有使用OpenCV,缺点是只能打开BMP文件(点击打开链接)。今天为了将方法改进,看了一些资料,经过自己的总结,得到了在Picture控件上显示Opencv处理过的图像的方法,以后可以直接在MFC+OpenCV平台下很容易地显示图像处理结果了。另外还发现,OpenCV提供的Mat类真是个好东西,里边封装的方法很像Matlab里边的函数,虽然没有使用,但是看了函数说明,是做的非常好的一个类,待以后探索吧。


今天的文章从两个地方得益良多:

(1)CvvImage取消带来的问题及解决 

(2)图像文件读入和显示

还有一个地方就是OpenCV的说明文档,这里不加链接了。

开始今天的话题:

1.平台:OpenCV2.4.6+VS2010

因为OpenCV 2.4.6版本不带CvvImage,带来了一些不便,所以今天才花了点功夫写成今天的程序。

2.代码

(1)首先是需要自己编写的ShowMat函数。

int CImgProcessorDlg::ShowMat(cv::Mat img, HWND hWndDisplay){if (img.channels()<3 )  {  return -1;  }  //构造将要显示的Mat版本图片RECT rect;  ::GetClientRect(hWndDisplay, &rect);  cv::Mat imgShow( abs(rect.top - rect.bottom), abs(rect.right - rect.left), CV_8UC3 );  resize( img, imgShow, imgShow.size() );  //在控件上显示要用到的CImage类图片ATL::CImage CI;  int w=imgShow.cols;//宽  int h=imgShow.rows;//高  int channels=imgShow.channels();//通道数  CI.Create( w, h, 8*channels);  //CI像素的复制uchar *pS;  uchar *pImg=(uchar *)CI.GetBits();//得到CImage数据区地址  int step=CI.GetPitch();  for(int i=0;i<h;i++)  {  pS=imgShow.ptr<uchar>(i);  for(int j=0;j<w;j++)  {  for(int k=0;k<3;k++)  *(pImg+i*step+j*3+k)=pS[j*3+k];  //注意到这里的step不用乘以3  }  }  //在控件显示图片HDC dc ;  dc = ::GetDC(hWndDisplay);  CI.Draw( dc, 0, 0 );  ::ReleaseDC( hWndDisplay, dc);  CI.Destroy();  return 0;}
(2)在按钮的响应函数调用刚刚写的ShowMat。

void CImgProcessorDlg::OnBnClickedBopen(){// TODO: 在此添加控件通知处理程序代码CString FilePath;CFileDialog FileDlg(TRUE);if (IDOK == FileDlg.DoModal()){//获取FileOpen对话框返回的路径名FilePath = FileDlg.GetPathName();//GetPathName返回的是CString类型,要经过转换为string类型才能使用imread打开图片std::stringpathName(FilePath.GetBuffer());//读取图片cv::Mat orgImg = cv::imread(pathName);//显示图片ShowMat(orgImg, GetDlgItem(IDC_PIMAGE)->GetSafeHwnd());}}
3.程序结果。


1 0