VC多媒体编程.docx
《VC多媒体编程.docx》由会员分享,可在线阅读,更多相关《VC多媒体编程.docx(127页珍藏版)》请在三一办公上搜索。
1、置顶 VC多媒体编程 分类: 软件开发 2007-04-28 14:09 14021人阅读 评论(8) 收藏 举报 编程nullmicrosoftwindowsgdi+文档-VC多媒体编程-Visual C+中基于多文档视窗模型的重叠图象拼接技术摘要 图象拼接是在全景视频系统、地理信息系统等应用中经常遇到的一个问题,本文基于网格匹配的方法对边界部分有重叠的图象提出了一种行之有效的对准算法,并通过平滑因子对图象实现了无缝拼接。并应用文档视窗模型实现了该算法,并完成了位图文件的显示、存储等操作,具有一定的普遍意义。 关键词: 图象拼接,算法,重叠图象,文档视窗,位图文件,图象显示 文章正文 一、多
2、文档视窗模型概述 MFC的AppWizard可以生成三种类型的应用程序:基于对话框的应用、单文档应用(SDI)和多文档应用(MDI)。三种应用中,以多文档应用(MDI)最为复杂,其功能也最强大。当我们用AppWizard生成一个多文档应用时,系统由CMultiDocTemplate自动生成了一个从Cdocument类继承的文档类,一个从Cview类继承的视窗类,一个从CMDIChildWnd类继承的框架类。当我们每次建立一个新的文档时,程序根据文档模板生成一个新实例,这些我们均可不用关心AppWizard已经自动生成了代码。但如果我们要在程序中使用多个不同的文档类时,则需自己建立文档模板并控制
3、文档实例的建立。假设我们要向一基于多文档的工程MDI中增加一Test的文档。具体步骤如下: 1、用Clazard建立一个框架类CTestFrame基类选CMDIChildWnd。 2、用Clazard建立一个文档类CTestDoc基类选CDocument。 3、用Clazard建立一个文档类CTestView基类选CView。 4、将三个类的头文件加入应用类CMDIApp中。 5、创建新文档模板,在CMDIApp:InitInstance()函数中加入如下代码 CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTempla
4、te( IDR_TESTTYPE, RUNTIME_CLASS(CTestDoc), RUNTIME_CLASS(CTestFrame), RUNTIME_CLASS(CTestView); AddDocTemplate(pDocTemplate); 6、定义一菜单项ID号为ID_NEWTEST,利用Clazard将其处理函数加入应用类(或主框架类),在其处理函数CMDIApp:OnNewtest()函数中加入如下代码 POSITION curTemplatePos = GetFirstDocTemplatePosition(); while(curTemplatePos != NULL) /
5、取下一个文档模板指针 CDocTemplate* curTemplate =GetNextDocTemplate(curTemplatePos); CString str; curTemplate-GetDocString(str, CDocTemplate:docName); /取文档名称 if(str = _T(Test) /判断当前文档文档是否Test类 curTemplate-OpenDocumentFile(NULL); /创建新的文档实例 return; 这样我们就建立了一个新的文档类。注意在5中创建文档模板时我们用到了一文档类型资源IDR_TESTTYPE,该资源ID在资源文件中
6、定义如下(未包括图标和菜单的定义): STRINGTABLE PRELOAD DISCARDABLE BEGIN . IDR_TESTTYPE/nTest/nTest/n/n/nMDI.Document/nTest Document END 文档类型标识包括七个子串,包括窗口标题、文档名称、文件扩展名等。在6中curTemplate-GetDocString(str, CDocTemplate:docName);取的就是第二个子串,文档名称。文档建立之后我们就可以对其进行操作了。当然文档类和视窗类,文档类和主窗口类,以及不同文档类之间进行通信也是较为复杂的,并非几句话就能说清楚,如不熟悉文档视
7、窗的读者请参看其它有关资料。 二、重叠图象拼接技术 1算法思想 在实现全景视频(Panoramic Video)系统、地理信息系统(GIS)及其它一些应用的过程中,我们通常会碰到这样的一个问题,就是要把几幅小的图象拼接成一幅大的图象。为了能让计算机自动对准图象我们要求待拼接的图象边界有部分重叠,计算机正是利用这些信息进行匹配对准。匹配算法的总体思想是既要保证对准的精度,又要保证运算量不至过大。这里算法利用了图象的自身特性,既在一般图象中,相邻的象素点的灰度值相差不大。因此,可在第二幅图象的边界取一个网格,然后将网格在第一幅图象上移动,计算所有网格点的两幅图象对应象素点的RGB值的差的平方和。记
8、录最小的值的网格位置,即认为是最佳匹配位置。(如图1)为了减小运算量,我们将匹配分为两个步骤,第一步是粗略匹配,在该阶段网格每次水平或垂直移动一个网格间距。在完成粗略匹配之后,我们在当前最佳匹配点处进行精确匹配,在该阶段以当前最佳匹配点为中心,网格向上下、左右各移动一个小步长。初始步长为粗略拼接时移动步长的一半,即为半个网格间距。不断的与当前最小平方和进行比较,如果比当前值优,就替换当前最佳匹配点。循环进行这个过程每次步长减半,直到水平步长和垂直步长均为0为止。 2算法描述 procedure ImageMatching 输入FirstImage; 输入SecondImage; /获得两幅图象
9、的大小 Height1=GetImageHeight(FirstImage); Height2=GetImageHeight(SecondImage); Width1=GetImageWidth(FirstImage); Width2=GetImageWidth(SecondImage); / 从第二幅图象取网格匹配模板 SecondImageGrid = GetSecondImageGrid(SecondImage); / 粗略匹配,网格在第一幅图象中先从左向右移动,再从下到上移动,每次移动一个网格间距,Step_Width 或Step_Height,当网格移出重叠区域后结束 y=Heith
10、t1-GridHeight; MinValue = MaxInteger; While ( yHeight1-OverlapNumber)/当网格移出重叠部分后结束 x=Grid_Width/2; /当网格位于第一幅图象的最左边时,A点的横坐标。 While ( x(Width1-Grid_Width/2) ) FirstImageGrid=GetImgaeGrid(FirstImgaeGrid, x, y); differ=CaculateDiff(FirstImgaeGrid, SecondImageGrid);/计算象素值差的平 /方和 if (differ0 & Step_Width0
11、)/当水平步长和垂直步长均减为零时结束 if(Step_Height=0)/当仅有垂直步长减为零时,将其置为1 Step_Height=1; If(Step_Width=0) /当仅有水平步长减为零时,将其置为1 Step_Width=1; temp_x = BestMatch_x; temp_y = BestMatch_y; for ( i= -1; i1; i+) for( j= -1; j1; j+) if (i=0&j!=0)|(i!=0&j=0) FirstImageGrid=GetImgaeGrid(FirstImgaeGrid, temp_x+i*Step_Width, temp
12、_y +j*Step_Height); differ=CaculateDiff(FirstImgaeGrid, SecondImageGrid); if (differ3(1) 假设位数组的起始指针为lpStartBits屏幕坐标(x,y)在的象素值的指针可用下式计算。 lpBits=lpStartBits + (WidthBytes*(Height-y-1) + x*biBitCount);(2) 其中WidthBytes为(1)式计算的值,Height为图象的高度。 3、 不同文档类之间的数据交换的实现 不同文档类之间的数据交换我们可以通过应用程序类或主窗口类作为媒介进行。在文档类或视窗类
13、可通过AfxGetApp()或AfxGetMainWnd()获得应用类和主窗口类的指针,在应用类和主窗口类则可以通过获得文档模板来获得文档类的指针来访问文档类的数据。这样我们可以通过应用类或主窗口类的成员变量进行数据交换了。 4、 图象的平滑连接 当找到最佳匹配点后,随后的工作将是把两幅图象合成一幅图象。对于重叠部分,我们如果只是简单的取第一幅图象或第二幅图象的数据,会造成图象的模糊和明显的边界,这是不能容忍的。即使取两幅图象的平均值,效果也不能令人满意。为了能使拼接区域平滑,保证图象质量,我们采用了渐入渐出的方法,即在重叠部分由第一幅图象慢慢过渡到第二幅图象,很自然我们可以想到设一渐变因子为
14、0dget_Width(&hmWidth); pPic-get_Height(&hmHeight); double fX,fY; fX = (double)pDC-GetDeviceCaps(HORZRES)*(double)hmWidth/(double)pDC-GetDeviceCaps(HORZSIZE)*100.0); fY = (double)pDC-GetDeviceCaps(VERTRES)*(double)hmHeight/(double)pDC-GetDeviceCaps(VERTSIZE)*100.0); if(FAILED(pPic-Render(*pDC,0,0,(DW
15、ORD)fX,(DWORD)fY,0,hmHeight,hmWidth,-hmHeight,NULL) AfxMessageBox(渲染图像失败!); pPic-Release(); else AfxMessageBox(从流中装载图像失败!); 其中,显示工作主要是由IPicture接口对象的Render函数来完成的,该函数主要用来将图片的指定部分画到指定的设备环境的指定位置。原型如下: HRESULT Render( HDC hdc, /渲染图像用的设备环境句柄 long x, /在hdc上的水平坐标 long y, /在hdc上的垂直坐标 long cx, /图像宽度 long cy,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VC 多媒体 编程
链接地址:https://www.31ppt.com/p-2012514.html