利用MFC的Picture控件显示和处理图像.docx

上传人:b****6 文档编号:6580537 上传时间:2023-01-08 格式:DOCX 页数:12 大小:214.10KB
下载 相关 举报
利用MFC的Picture控件显示和处理图像.docx_第1页
第1页 / 共12页
利用MFC的Picture控件显示和处理图像.docx_第2页
第2页 / 共12页
利用MFC的Picture控件显示和处理图像.docx_第3页
第3页 / 共12页
利用MFC的Picture控件显示和处理图像.docx_第4页
第4页 / 共12页
利用MFC的Picture控件显示和处理图像.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

利用MFC的Picture控件显示和处理图像.docx

《利用MFC的Picture控件显示和处理图像.docx》由会员分享,可在线阅读,更多相关《利用MFC的Picture控件显示和处理图像.docx(12页珍藏版)》请在冰豆网上搜索。

利用MFC的Picture控件显示和处理图像.docx

利用MFC的Picture控件显示和处理图像

利用MFC的Picture控件显示和处理图像

Wikipedia,自由的百科全书

在《OpenCV教程-基础篇》的2.8节中,所创建的MFC图像显示是直接放在对话框面板的左上角的,感觉不大美观;《MFC中快速应用OpenCV》则是介绍用SDI(单文档界面)来显示图像,《Astep-by-stepguidetotheuseofMicrosoftVisualC++andtheIntelOpenCVlibrary》使用VS2005来进行图像和视频的读取和处理,但是其图像和视频的显示界面不是在对话框里面的,而是新建一个窗口来做。

所以下面我们就来看看怎么在对话框里使用Picture控件来显示和处理图像。

[编辑]

创建MFC

首先创建一个MFC对话框应用程序(Dialog-basedApplication)如下:

在VS2005和2008里,我们可以用一个Solution来组合几个Project(每个Project基本上只包含一个Program),当我们要构建一个多Program的应用时(例如一个客户端程序加一个服务器应用程序),利用Solution可以将这些Projects组合起来、并且共享文件和函数库。

通常需要为Solution创建一个主路径,其中包含了所有Projects的路径。

不过在这篇文章里,我们只构建一个简单的Project,所以在创建MFC的NewProject对话框里,不用勾选“Createdirectoryforsolution”这个选项。

点击OK--Next进入下一步,在这里我们创建一个Dialog-basedApplication,大部分选项按默认设置就行,不过最下面的“UseUnicodelibraries”最好去掉。

如果勾选了这个选项,程序代码就会使用16bit的Unicode字符集来编码,但是很多函数虽然使用char*(ASCIIstings)类型字符,而将字符串从Unicode转换到ASCII是非常麻烦的。

使用Unicode在编译时可能会遇到下列错误:

cannotconvertparameter1from'CString'to'constchar*'

cannotconvertfrom'constchar[11]'to'LPCWSTR'

这意味着在Unicode和Multi-byte字符串的转换中出现了问题。

在上一篇学习笔记中,就提到“成员函数LoadBMP其输入参数类型应为constchar*”,那应该只是一个治标的方法,这里的去掉“UseUnicodelibraries”选项,才是治本之道。

往后的几步设置,可以根据自己的需要来操作,我的设置如下:

[编辑]

编写代码

在ResourceView面板->mymfc(工程名称)->mymfc.rc->Dialog双击IDD_MYMFC_DIALOG,可以看到一个初始的GUI界面,往里面添加两个Button和一个Picture控件,如下:

选中单个控件、右击选择属性(Properties),可以看到控件的ID号,这个号可以自行编辑,例如Picture控件的ID号我设置为IDC_ShowImg,这个ID号在后面的图像显示函数中要用到。

首先在项目属性中加载lib文件:

菜单Project->Properties->ConfigurationProperties->Linker–>Input->additionaldependencies中加入cxcore200.libcv200.libhighgui200.lib。

然后在mymfc.h的#include"resource.h"下加入如下代码:

#include"cv.h"

#include"highgui.h"

 

#defineIMAGE_WIDTH256

#defineIMAGE_HEIGHT256

#defineIMAGE_CHANNELS3

在ClassView面板右击CmymfcDlg,选择Add–>AddVariable,添加一个IplImage*类型的变量TheImage;再点击CmymfcDlg,在下面窗口的列表中双击OnInitDialog,在“//TODO:

Addextrainitializationhere”下面添加TheImage的初始化代码:

CvSizeImgSize;

ImgSize.height=IMAGE_HEIGHT;

ImgSize.width=IMAGE_WIDTH;

TheImage=cvCreateImage(ImgSize,IPL_DEPTH_8U,IMAGE_CHANNELS);

然后双击OnPaint,在if(IsIconic())…的else里添加以下代码,用来重绘窗口:

CDialog:

:

OnPaint();

//重绘对话框

CDialog:

:

UpdateWindow();

//更新windows窗口,如果无这步调用,图片显示还会出现问题

ShowImage(TheImage,IDC_ShowImg);

//重绘图片函数

接着在CmymfcApp下面的成员列表中双击InitInstance,在两个“//TODO:

Placecodeheretohandlewhenthedialogis…”下面添加:

cvReleaseImage(&dlg.TheImage);

即按下“OK”或“Cancel”时,释放TheImage占用的内存。

接下来就是写读取和处理图片的功能函数了。

回到mymfc的GUI编辑界面中,右击按钮ReadImg,选择AddEventHandler,建立按钮点击的消息响应程序:

句柄名设置为OnBnClickedReadimg,主要的响应操作包括弹出对话框选择图片文件、读入图片文件、对图片统一缩放至256*256的大小、显示图像,代码如下:

//TODO:

Addyourcontrolnotificationhandlercodehere

//选项图片的约定

CFileDialogdlg(

TRUE,_T("*.bmp"),NULL,

OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,

_T("imagefiles(*.bmp;*.jpg)|*.bmp;*.jpg|AllFiles(*.*)|*.*||"),NULL

);

//打开文件对话框的标题名

dlg.m_ofn.lpstrTitle=_T("OpenImage");

//判断是否获得图片

if(dlg.DoModal()!

=IDOK)

return;

//获取图片路径

CStringmPath=dlg.GetPathName();

//读取图片、缓存到一个局部变量ipl中

IplImage*ipl=cvLoadImage(mPath,1);

//判断是否成功读取图片

if(!

ipl)

return;

//对上一幅显示的图片数据清零

if(TheImage)

cvZero(TheImage);

//对读入的图片进行缩放,使其宽或高最大值者刚好等于256,再复制到TheImage中

ResizeImage(ipl);

//调用显示图片函数

ShowImage(TheImage,IDC_ShowImg);

//释放ipl占用的内存

cvReleaseImage(&ipl);

其中包含了两个新的成员函数ResizeImage和ShowImage,前者的作用是对读入的不同大小的图像进行缩放,再通过设置ROI的方式将图像存入256*256的TheImage中;后者是将图像TheImage显示到图片显示控件IDC_ShouImg窗口的正中部位。

为了实现这两个功能,首先在ClassView面板右击CmymfcDlg,选择Add–>AddFunction,创建两个函数:

voidShowImage(IplImage*img,UINTID)和voidResizeImage(IplImage*img)。

以下是这两个函数的实现代码:

voidCmymfcDlg:

:

ResizeImage(IplImage*img)

{

//读取图片的宽和高

intw=img->width;

inth=img->height;

 

//找出宽和高中的较大值者

intmax=(w>h)?

w:

h;

 

//计算将图片缩放到TheImage区域所需的比例因子

floatscale=(float)((float)max/256.0f);

 

//缩放后图片的宽和高

intnw=(int)(w/scale);

intnh=(int)(h/scale);

 

//为了将缩放后的图片存入TheImage的正中部位,需计算图片在TheImage左上角的期望坐标值

inttlx=(nw>nh)?

0:

(int)(256-nw)/2;

inttly=(nw>nh)?

(int)(256-nh)/2:

0;

 

//设置TheImage的ROI区域,用来存入图片img

cvSetImageROI(TheImage,cvRect(tlx,tly,nw,nh));

 

//对图片img进行缩放,并存入到TheImage中

cvResize(img,TheImage);

 

//重置TheImage的ROI准备读入下一幅图片

cvResetImageROI(TheImage);

}

 

 

voidCmymfcDlg:

:

ShowImage(IplImage*img,UINTID)//ID是PictureControl控件的ID号

{

//获得显示控件的DC

CDC*pDC=GetDlgItem(ID)->GetDC();

//获取HDC(设备句柄)来进行绘图操作

HDChDC=pDC->GetSafeHdc();

 

CRectrect;

GetDlgItem(ID)->GetClientRect(&rect);

//求出图片控件的宽和高

intrw=rect.right-rect.left;

intrh=rect.bottom-rect.top;

//读取图片的宽和高

intiw=img->width;

intih=img->height;

//使图片的显示位置正好在控件的正中

inttx=(int)(rw-iw)/2;

intty=(int)(rh-ih)/2;

SetRect(rect,tx,ty,tx+iw,ty+ih);

//复制图片

CvvImagecimg;

cimg.CopyOf(img);

//将图片绘制到显示控件的指定区域内

cimg.DrawToHDC(hDC,&rect);

 

ReleaseDC(pDC);

}

函数ResizeImage是参考了学习笔记(5)中单窗口显示多幅图像的函数cvShowMultiImages修改而成的,函数ShowImage则是参考了帖子《OpenCV如何把图像显示到MFC的picture控件上》的代码,另外下面几个帖子也可以参考:

1、《MFCpicturecontrol画框的问题》

2、《MFCpicturecontrol控件实现(隐藏)文字显示》

3、《MFC在PictureControl中显示图片(jpg)遇到的问题》

4、《vc怎样在picturecontrol中显示jpg,jif,bmp格式图象》

5、《使用PictureControl显示BMP图片》

最后是要对读入的图像做简单的Canny边缘处理,为此,建立一个按钮EdgeDetect,相应的响应代码如下:

voidCmymfcDlg:

:

OnBnClickedEdgedetect()

{

//TODO:

Addyourcontrolnotificationhandlercodehere

IplImage*gray=0,*edge=0;

gray=cvCreateImage(cvSize(IMAGE_WIDTH,IMAGE_HEIGHT),IPL_DEPTH_8U,1);

edge=cvCreateImage(cvSize(IMAGE_WIDTH,IMAGE_HEIGHT),IPL_DEPTH_8U,1);

cvCvtColor(TheImage,gray,CV_BGR2GRAY);

cvCanny(gray,edge,30,100,3);

cvCvtColor(edge,TheImage,CV_GRAY2BGR);

ShowImage(TheImage,IDC_ShowImg);//调用显示图片函数

 

cvReleaseImage(&gray);

cvReleaseImage(&edge);

}

这里主要是参考了《OpenCV教程-基础篇》P33的代码,不过并没有像书中那样创建新的MyIplClass类来进行图像的读取和处理操作。

我觉得这篇文章中直接对TheImage进行处理可能不大妥当,按照教程那样新建一个类来处理才是比较稳妥吧。

这里涉及到函数返回对象实例的过程、深拷贝和浅拷贝、拷贝构造、动态内存的使用、opencv相关接口的代码等方面,以后还要进一步深入学习和理解!

我们还可以在ResourceView面板->mymfc(工程名称)->mymfc.rc->Version中修改程序的产品版本、名称等信息。

来看看程序生成后的效果:

可以到这里下载源码:

取自"

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1