




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、面向对象程序设计学 号:130085210002 学生所在学院:信息工程学院学 生 姓 名 :邵丽群任 课 教 师 :熊邦书教师所在学院:信息工程学院2013级 实现图像的几何变换电子信息工程信息工程学院摘要:几何变换是最常见的图像处理手段,通过对变形的图像进行几何校正,可以得出准确的图像。常用的几何变换功能包括图像的平移、图像的镜像变换、图像的转置、图像的缩放、图像的旋转等等。目前数字图像处理的应用越来越广泛,已经渗透到工业、航空航天、军事等各个领域,在国民经济中发挥越来越大的作用。作为数字图像处理的一个重要部分,本文接受的工作是如何Visual C+编程工具设计一个完整的应用程序
2、,实现经典的图像几何变换功能。程序大概分为两大部分:读写BMP图像,和数字图像的几何变换。即首先用Visual C+创建一个单文档应用程序框架,在实现任意BMP图像的读写,打印,以及剪贴板操作的基础上,完成经典的图像几何变换功能。图像几何变换的Visual C+编程实现,为校内课题的实现提供了一个实例。 关键字:图像处理;几何变换(图像的平移、缩放、转置、旋转和镜像变换);BMP图像;Visual C+一、引言图像几何变换是指用数学建模的方法来描述图像位置、大小、形状等变化的方法。在实际场景拍摄到的一幅图像,如果画面过大或过小,都需要进行缩小
3、或放大。如果拍摄时景物与摄像头不成相互平行关系的时候,会发生一些几何畸变,例如会把一个正方形拍摄成一个梯形等。这就需要进行一定的畸变校正。在进行目标物的匹配时,需要对图像进行旋转、平移等处理。在进行三维景物显示时,需要进行三维到二维平面的投影建模。因此,图像几何变换是图像处理及分析的基础。 图像几何变换是计算机图像处理领域中的一个重要组成部分,也是值得深讨的一个重要课题。在图像几何变换中主要包括图像的放缩、图像的旋转、图像的移动、图像的镜像、图像的块操作等内容,几何变换不改变图像的像素值,只改变像素所在的几何位置。从广义上说,图像是自然界景物的客观反映,是人类认识世界和人类本身的重要
4、源泉。图像对我们并不陌生。我们生活在一个信息时代,科学研究和统计表明,人类从外界获得的信息约有75%来自视觉系统,也就是从图像中获得的。所以对数字图像的处理便显得尤为重要了。本文主要深讨了图像的几何变换(主要包括图像的平移、转置、缩放、旋转、镜像等)理论,并在此基础上用Visual C+实现的过程。1.3.2研究方法方法一:利用 Windows 本身就提供了一个API函数SetWorldTransForm来实现图片旋转、位移及其他变形,这个函数是对一个设备上下文DC进行操作,通过坐标转换来实现各种功能的。方法二:通过图像进行平移、旋转、转置、镜像、缩放后重新计算各点新像素完成几何变换。自定义一
5、个图像处理的Cdibapi类,把一般处理图像时要用到的函数实现封装在这个类中,该类用于实现DIB对象的绘制,DIB对象调色板的创建,DIB对象的读取与存储,图像线性变换,图像灰度拉伸等。然后把在视类中实现图像平移,图像镜像,图像转置,图像缩放及图像旋转的函数调用和实现。二、正文2.1灰度图灰度图(Grayscale)是指只含亮度信息,不含色彩信息的图像。因此,要表示灰度图,就需要把亮度值进行量化。通常划分为0到255共256个级别,0最暗(全黑),255最亮(全白)。BMP格式的文件中并没有灰度图这个概念,但是可以很容易的用BMP文件来表示灰度图。方法是用256色的调色板,只不过这个调色板有点
6、特殊,每一项的RGB值都是相同的。也就是说RGB值从(0,0,0),(1,1,1)一直到(255,255,255)。(0,0,0)是全黑色,(255,255,255)是全白色,中间的是灰色。2.2调色板调色板结构LOGPALETTE,该结构定义如下:typedef struct tagLOGPALETTE WORD palVersion;/调色板的板本号,应该指定该值为0x300;WORD palNumEntries;/调色板中的表项数,对于灰度图像该值为256; PALETEENTRY palPalEntry1;/调色板中的颜色表项,由于该表项的数 目不一定,所以这里数组长度定义为1,灰度图
7、像对应的该数组的长度为256LOGPALETTE;颜色表项结构PALETTEENTRY定义了调色板中的每一个颜色表项的颜色和使用方式,定义如下:typedef struct tagPALETTEENTRYBYTE peRed; /R分量值;BYTE peGreen; /G分量值;BYTE peBlue; /B分量值; BYTE peFlags; / 该颜色被使用的方式,一般情况下设为"0";PALETTEENTRY;Windows系统使用调色板管理器来管理与调色板有关的操作,通常活动窗口的调色板即是当前系统调色板,所有的非活动窗口都必须按照此系统调色板来显示自己的颜色,此时
8、调色板管理器将自动的用系统调色板中的最近似颜色来映射相应的显示颜色。如果窗口或应用程序按自己的调色板显示颜色,就必须将自己的调色板载入到系统调色板中,这种操作叫作实现调色板,实现调色板包括两个步骤:1. 首先将调色板选择到设备上下文中,可以通过CDC:SelectPalette() 选入设备上下文2. 然后在设备上下文中实现调色板,可以通过 CDC:RealizePalette()实现设备调色板。1.2.4 BMP文件中DIB的结构DIB是标准的Windows位图格式,BMP文件中包含了一个DIB。一个BMP文件大体上分成如下4个部分:bfType=”BM”
9、bfSize bfReserved1 bfReserved2 bfOffBits BITMAPFILEHEADER 位图文件头 (只用于BMP文件) biSize biWidth biHeightbiPlanes biBitCount biCompression biSizeImage biXPelsPerMeter biYPelsPerMeter biClrUsed biClrImportant BITMAPINFOHEADER 位图信息头 单色DIB有
10、2个表项 16色DIB有16个表项或更少256色DIB有256个表项或更少 真彩色DIB没有调色板 每个表项长度为4字节(32位)像素按照每行每列的顺序排列 每一行的字节数必须是4的整数 Palette调色板 DIB Pirxels DIB图像数据2.3图像的几何变换基础知识图像的几何变换,通常包括图像的平移、图像的镜像变换、图像的转置、图像的缩放和图像的旋转等。程序结束图像的缩放图像的转置图像的镜像图像的平移程序开始读写BMP图像图像的旋转图2.1 程序基本框架图2.3.1图像的平移图像的平移是几何变换中最简单的变换之一。图像平
11、移就是将图像中所有的点都按照指定的平移量水平、垂直移动。设(x0,y0)坐标将变为(x1,y1)。显然(x0,y0)和(x1,y1)的关系如下:x1=x0+txy1=y0+ty用矩阵表示如下:x1y11=1 0 tx0 1 ty0 0 1x0y01对该矩阵求逆,可以得到逆变换:x0y01=1 0 -tx0 1 -ty0 0 1x1y11即x0=x1-txy0=y1-ty这样,平移后的图像上的每一点都可以在原图像中找到对应的点。例如,对于新图中的(0,0)像素,代入上面的方程组,可以求出对应原图中的像素(-tx,-ty)。如果tx或ty大于0,则(-tx,-ty)不在原图中。对于不在原图中的点,
12、可以直接将它的像素值统一设置为0或则255(对于灰度图就是黑色或白色)。同样,若有点不在原图中,也就说明原图中有点被移出显示区域。如果不想丢失被移出的部分图像,可以将新生成的图像宽度扩大|tx|,高度扩大|ty|。2.3.2图像的镜像图像的镜像变换分为两种:一种是水平镜像,另外一种是垂直镜像。图像的水平镜像操作是将图像的左半部分和右半部分以图像垂直中轴线为中心镜像进行对换;图像的垂直镜像操作是将图像上半部分和下半部分以图像水平中轴线为中心镜像进行对换。设图像高度为lHeight,宽度为lWidth,原图中(x0,y0)经过水平镜像后坐标将变为(lWidth-x0,y0),其矩阵表达式为:x1y
13、11=-1 0 lWidth0 1 ty0 0 1x0y01逆运算表达式为:x0y01=-1 0 lWidth0 1 00 0 1x1y11即同样,(x0,y0)经过垂直镜像后坐标将变为(x0,lHeight-y0),其矩阵表达式为:x1y11=1 0 0 0 -1 lHeight 0 0 1 x0y01逆运算矩阵表达式为:x0y01=1 0 0 0 -1 lHeight 0 0 1 x1y11 即x0=x1y0=lHeight-y12.3.3图像的转置图像的转置操作是将图像像素的x坐标和y坐标互换。该操作将改变图像的大小,图像的高度和宽度将互换。转置表达式:x1y11=1 0 tx0 1 t
14、y0 0 1x0y01它的逆矩阵表达式:x0y01=1 0 tx0 1 ty0 0 1x1y11 即x0=x1y0=y12.3.4图像的缩放上面的几种图像几何变换中都是1:1的变换,而图像的缩放操作将会改变图像的大小,产生的图像中的像素可能在原图中找不到相应的像素点,这样就必须进行近似处理。一般的方法是直接赋值为和它最相近的像素值,也可以通过一些插值算法来计算。下面的代码直接采用了前一种做法。假设图像x轴方向缩放比率为fx,y轴方向缩放比率为fy,那么原图中点(x0,y0)对应与新图中的点(x1,y1)的转换矩阵为:x1y11=fx 0 00 fy 00 0 1x0y01其逆运算如下:x0y0
15、1=1/fx 0 0 0 1/fy 0 0 0 1x1y11 即x0=x1/fxy0=y1/fy例如,当fx=fy=0.5时,图像被缩放到一半大小,此时缩小后图像中的(0,0)像素对应于原图中的(0,0)像素;(0,1)像素对应于原图中的(0,2)像素;(1,0)像素对应于原图中的(2,0)像素,以此类推。在原图基础上,每行隔一个像素取一点,每隔一行进行操作。其实是将原图每行中的像素重复取值一遍,然后每行重复一次。2.3.5图像的旋转一般图像的旋转是以图像的中心为原点,旋转一定的角度。旋转后,图像的大小一般会改变。和图像平移一样,既可以把转出显示区域的图像截去,也可以扩大图像范围以显示所有的图
16、像。可以推导一下旋转运算的变换公式。如下图所示,点(x0,y0)经过旋转度后坐标变成(x1,y1)。在旋转前:x0=cos()y0=sin()转置后:x1=cos-=cos()cos()+sin()sin()=x0cos()+y0sin()y1=sin-=sincos-cossin=-x0sin()+y0cos()写成矩阵表达式为:x1y11= cos sin() 0-sin cos() 0 0 0 1x0y01其逆运算如下:x0y01= cos -sin() 0sin cos() 0 0 0 1x1y11有了上面的转换公式,就可以非常方便的编写出实现图像旋转的函数。首先应计算出公式中需要的几
17、个参数:a,b,c,d和旋转后新图像的高、宽度。现在已知图像的原始宽度为lWidth,高度为lHeight,以图像中心为坐标系原点,则原始图像四个角的坐标分别为-lWidth-12,lHeight-12, lWidth-12,lHeight-12, lWidth-12,-lHeight-12和 -lWidth-12,-lHeight-12,按照旋转公式,在旋转后的新图中,这四个点坐标为:fDstX1,fDstY1=-lWidth-12cos+lHeight-12sin,lWidth-12sin()+lHeight-12cos()fDstX2,fDstY2=lWidth-12cos+lHeigh
18、t-12sin,-lWidth-12sin()+lHeight-12cos()fDstX1,fDstY1=lWidth-12cos-lHeight-12sin,-lWidth-12sin-lHeight-12cos()fDstX1,fDstY1=-lWidth-12cos-lHeight-12sin,lWidth-12sin-lHeight-12cos()则新图像的宽度lNewWidth和高度lNewHeight为:lNewWidth=maxfDstX4-fDstX1,fDstX3-fDstX2lNewHeight=maxfDstY4-fDstY1,fDstY3-fDstY2令f1=-ccos
19、-dsin+af2=csin-dcos+b,其中a=lWidth-12, b=lHeight-12, c=lNewWidth-12, b=lNewHeight-12,则x0=x1cos+y1sin+f1y0=-x1sin+y1cos+f22.4 Visual C+简述VisualC+是微软公司提供的基于C/C+的应用程序集成开发工具。VC拥有丰富的功能和大量的扩展库,使用它能有效的创建高性能的Windows应用程序和Web应用程序。VC的优越性主要表现在以下几个方面:开发分布式应用、开发的应用程序运行效率高、具有健壮性、能缩短软件升级周期。能够生成多线程应用,而多线程应用对于增加并发
20、响应有实际意义。VC除了提供高效的C/C+编译器外,还提供了大量的可重用类和组件,包括著名的微软基础类库(MFC)和活动模板类库(ATL),因此它是软件开发人员不可多得的开发工具。将Visual C+应用于数字图像的几何变换,VC丰富的功能和大量的扩展库,类的重用特性以及它对函数库、DLL库的支持能使程序更好的模块化,并且通过向导程序大大简化了库资源的使用和应用程序的开发,正由于VC具有明显的优势,因而我选择了它来作为数字图像几何变换的开发工具。在本程序的开发过程中,VC的核心知识、消息映射机制、对话框控件编程等都得到了生动的体现和灵活的应用。三、实验步骤及结果3.1 通过API函数
21、SetWorldTransForm实现图像几何变换API函数SetWorldTransForm实现图像几何变换使用XFORM来控制DC时,需要先设置绘图模式SetGraphicsMode为GM_ADVANCED,再用SetWorldTransform。否则SetWorldTransform函数会失败。setWorldTransForm内部的算法其实相当于用线性代数里矩阵与一个向量相乘的办法来解决图形的变换,只要我们知道要乘上的变换方程是哪一个,就能进行各种变换(不止是旋转), 这个函数是对一个设备上下文DC进行操作,通过坐标转换来实现各种功能的。函数原型:int SetGraphicsMode
22、(HDC hdc, int iMode);参数:hdc:指向设备环境的句柄。 iMode:指定图形模式,该参数取值参看MSDN函数原型:BOOL SetWorldTransform(HDC hdc, CONST XFORM *lpXform);参数:hdc:指向设备环境的句柄。 lpxform:指向XFORM结构的指针,此结构含有转换数据。返回值:如果函数调用成功,返回值为非零值,否则为零。编程原理:对于选定DC的任何坐标(x, y)将被SetWindowsForm设定的变换转换为坐标(x, y),两个坐标的对应关系是: x = x * eM11
23、0;+ y * eM12 + eDx;y = x * eM12 + y * eM22 + eDy;对于一个转换的操作,数学上的转换方式是:x2 = cos(q)*(x1-x0) sin(q)*(y1-y0) + x0;y2 = sin(q)*(x1-x0) + cos(q)*(y1-y0) + y0;于是,我们可以得到SetW
24、orldTransForm的一组参数:xform.eM11 = cos(q);xform.eM12 = sin(q);xform.eM21 = -sin(q);xform.eM22 = cos(q); xform.eDx = x0-cos(q)*x0+sin(q)*y0; xform.eDy = y0-cos(q)*y0-sin(q)*x0;实验步骤:一、先新建一个对话框的应用程序; 二、修改对话框的属性将其Caption属性改为“图片处理”,Border属性改为“Resiz
25、ing”,为其添加一些控件并未其中的而一些控件关联变量且修改控件的属性如图:三、为旋转、缩放、平移控件添加消息处理及绘制矩形和椭圆、旋转DC等代码3.1.1图像旋转的代码及结果:if ( m_iAngle != 0 ) fangle = (double)m_iAngle / 180. * 3.1415926; xform.eM11 =(float)cos(fangle); xform.eM12 = (float)sin(fangle); xform.eM21 =(float)-sin(fangle); xform.eM22 =(float)cos(fangle); xform.eDx = (f
26、loat)(centerPt.x - cos(fangle)*centerPt.x + sin(fangle)*centerPt.y); xform.eDy = (float)(centerPt.y - cos(fangle)*centerPt.y - sin(fangle)*centerPt.x); SetWorldTransform(hDc, &xform); 实验结果:旋转前图像 旋转23°的图像 旋转123°的图像 旋转312°的图像3.1.2图像缩放的代码及结果试验代码:if ( m_iSize != 1 ) fangle = (double)m
27、_iAngle / 180. * 3.1415926; xform.eM11 =m_iSize*(float)cos(fangle); xform.eM12 = m_iSize*(float)sin(fangle); xform.eM21 =m_iSize*(float)-sin(fangle); xform.eM22 =m_iSize*(float)cos(fangle); xform.eDx = (float)(centerPt.x - m_iSize*cos(fangle)*centerPt.x + m_iSize*sin(fangle)*centerPt.y+m_iPanLeft);
28、xform.eDy = (float)(centerPt.y - m_iSize*cos(fangle)*centerPt.y - m_iSize*sin(fangle)*centerPt.x+m_iPanRight); SetWorldTransform(hDc, &xform); 实验结果: 缩放前的图像 放大2.5倍的图像缩小0.5倍的图像 放大2.5倍且旋转50°的图像3.1.3图像平移的代码及结果实验代码:if ( m_iPanLeft != 0|m_iPanRight!=0 ) fangle = (double)m_iAngle / 180. * 3.141592
29、6; xform.eM11 =(float)cos(fangle); xform.eM12 = (float)sin(fangle); xform.eM21 =(float)-sin(fangle); xform.eM22 =(float)cos(fangle); xform.eDx = (float)(centerPt.x - cos(fangle)*centerPt.x + sin(fangle)*centerPt.y+m_iPanLeft); xform.eDy = (float)(centerPt.y - cos(fangle)*centerPt.y - sin(fangle)*cen
30、terPt.x+m_iPanRight); SetWorldTransform(hDc, &xform); 实验结果:平移前的图像 横向平移56.5纵向平移45的图像横向平移56纵向平移45且旋转45° 横向平移-56纵向平移-45的图像 放大2倍的图像3.2通过像素来实现图像的几何变换实验步骤:先新建一个基类为CScrollView的单文档应用程序然后新添加一个图像处理的Cdibapi类,把一般处理图像时要用到的函数实现封装在这个类中,该类用于实现DIB对象的绘制,DIB对象调色板的创建,DIB对象的读取与存储,图像线性变换,图像灰度拉伸等。然后为菜单栏添加一些新的菜单最后
31、在视图类为新添加的菜单项添加消息处理函数3.2.1图像的平移有了上面的理论基础,可以十分容易的用Visual C+来实现图像的平移。在这里,只介绍灰度图像的平移,因为灰度图像每个像素位数正好是8位,即1个字节,这样,可以不必考虑拼凑字节的问题。而且由于灰度图调色板的特殊性,处理时不必考虑调色板的问题。根据上面的公式可以得到图像的平移程序流程图:程序开始单击“文件”->“打开”打开一幅图像单击“几何变换”->图像平移获取水平平移量和垂直平移量 计算指向新DIB第i行,第j个像素的指针提示用户将该像素赋值为255 程序结束是 程序结束设置脏标记
32、更新视图复制平移后的图像直接复制像素判断平移是否成功计算指向原DIB在该坐标下像素的指针计算该像素在原DIB中的坐标判断坐标是否在原图范围内否否 图3.1图像平移程序流程图平移实现代码:void CImg_TransformView:OnGeomTran() CImg_TransformDoc* pDoc = GetDocument();LPSTRlpDIB; LPSTR lpDIBBits;lpDIB = (LPSTR) :GlobalLock(HGLOBAL) pDoc->GetHDIB();if (:DIBNumColors(lpDIB) != 256)MessageBox(&qu
33、ot;目前只支持256色位图的平移!", "系统提示" , MB_ICONINFORMATION |MB_OK);:GlobalUnlock(HGLOBAL) pDoc->GetHDIB();return;float XOffset; float YOffset;CTransDlg dlg;dlg.m_Xoffset=10; dlg.m_Yoffset=10; if(dlg.DoModal ()!=IDOK)return ;XOffset=dlg.m_Xoffset ;YOffset=dlg.m_Yoffset ;delete dlg;lpDIBBits=:
34、FindDIBBits(lpDIB);if (TranslationDIB(lpDIBBits, :DIBWidth(lpDIB), :DIBHeight(lpDIB), XOffset, YOffset) pDoc->SetModifiedFlag(TRUE); pDoc->UpdateAllViews(NULL);elseMessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK);:GlobalUnlock(HGLOBAL) pDoc->GetHDIB();平移实现结果:平移
35、前的图像 水平平移50垂直平移50的图像 3.2.2图像的镜像图像的镜像变换分为两种:一种是水平镜像,另外一种是垂直镜像。图像的水平镜像操作是将图像的左半部分和右半部分以图像垂直中轴线为中心镜像进行对换;图像的垂直镜像操作是将图像上半部分和下半部分以图像水平中轴线为中心镜像进行对换。按照上面的变换公式,可以非常简单的实现图像的水平和垂直镜像操作。下图是镜像操作的程序流程图:程序开始单击“文件”->“打开”打开一幅图像否是否水平镜像针对每行图像左半部分进行操作针对上半图像进行操作操作 计算指向倒数第i行像素起点的指针计算指向倒数第i行,第j个像素的指针计算指向第i行像素起点的指针计算指向倒
36、数第i行,倒数第j个像素的指针备份一行备份一个像素将倒数第i行像素复制到第i行将倒数第i行,第j个像素复制到倒数第i行,倒数第j个像素将倒数第i行,倒数第j个像素复制到倒数第i行,第j个像素将第i行像素复制到倒数第i行 否提示用户 程序结束是 程序结束设置脏标记更新视图判断镜像是否成功镜像实现的代码:void CImg_TransformView:OnGeomMirv() CImg_TransformDoc* pDoc = GetDocument();LPSTRlpDIB; LPSTR lpDIBBits;lpDIB = (LPSTR) :GlobalLock(HGLOBA
37、L) pDoc->GetHDIB();if (:DIBNumColors(lpDIB) != 256)MessageBox("目前只支持256色位图的镜像!", "系统提示" , MB_ICONINFORMATION | MB_OK);:GlobalUnlock(HGLOBAL) pDoc->GetHDIB();return;int bDirection;CMirvDlg dlg; if(dlg.DoModal ()!=IDOK)return ;bDirection=dlg.m_bDirection ;delete dlg;lpDIBBits
38、=:FindDIBBits(lpDIB);if(MirrorDIB(lpDIBBits,:DIBWidth(lpDIB), :DIBHeight(lpDIB),bDirection)pDoc->SetModifiedFlag(TRUE);pDoc->UpdateAllViews(NULL);elseMessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK);:GlobalUnlock(HGLOBAL) pDoc->GetHDIB()镜像实验结果: 镜像前的图像 水平镜像的图像 垂
39、直镜像的图像3.3图像的转置图像转置的实现和图像镜像变换相似,不同之处在于图像转置后DIB的头文件也要进行相应的改变,主要是将头文件中图像高度和宽度信息更新。因此传递给图像转置函数的参数是直接指向DIB的指针,而不是直接指向DIB像素的指针。根据公式可以得到如下所示的程序流程图:程序开始单击“文件”->“打开”打开一幅图像单击“几何变换”->图像转置针对每行图像每列进行操作 计算指向原DIB第i行,第j个像素的指针计算指向转置DIB第j行,第i个像素的指针复制转置后的图像复制像素互换DIB中图像的高宽否提示用户 程序结束是 程序结束设置脏标记更新视图判断转置是否
40、成功 图3.3 图像转置的程序流程图图像转置代码:void CImg_TransformView:OnGeomTrpo()CImg_TransformDoc* pDoc = GetDocument();LPSTRlpDIB;LPSTR lpDIBBits;lpDIB = (LPSTR) :GlobalLock(HGLOBAL) pDoc->GetHDIB();if (:DIBNumColors(lpDIB) != 256)MessageBox("目前只支持256色位图的转置!", "系统提示" , MB_ICONINFORMATION | MB_O
41、K);:GlobalUnlock(HGLOBAL) pDoc->GetHDIB();return;if(TransposeDIB(lpDIB)pDoc->SetModifiedFlag(TRUE);pDoc->UpdateAllViews(NULL);elseMessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK);转置实验结果:转置前的图像 转置后的图像3.2.4图像的缩放上面的几种图像几何变换中都是1:1的变换,而图像的缩放操作将会改变图像的大小,产生的图像中的像素可能在原
42、图中找不到相应的像素点,这样就必须进行近似处理。一般的方法是直接赋值为和它最相近的像素值,也可以通过一些插值算法来计算。下面的代码直接采用了前一种做法。按照上面的转换公式,可以容易的写出图像的缩放程序流程图:程序开始 单击“文件”->“打开”打开一幅图像单击“几何变换”->图像缩放获取水平缩放量和垂直缩放量 更新DIB中图像的高度和宽度针对图像每行每列进行操作计算指向原DIB第i行,第j个像素的指针计算指向转置DIB第j行,第i个像素的指针复制转置后的图像复制像素互换DIB中图像的高宽否提示用户 程序结束是 程序结束设置脏标记更新视图判断转置是否成功 3.4图像
43、缩放的程序流程图图像缩放代码:void CImg_TransformView:OnGeomZoom()CImg_TransformDoc* pDoc = GetDocument();LPSTR lpDIB;lpDIB = (LPSTR) :GlobalLock(HGLOBAL) pDoc->GetHDIB();if (:DIBNumColors(lpDIB) != 256)MessageBox("目前只支持256色位图的缩放!", "系统提示" , MB_ICONINFORMATION | MB_OK);:GlobalUnlock(HGLOBAL)
44、 pDoc->GetHDIB();return;float fXZoomRatio;float fYZoomRatio;CZoomDlg dlg;dlg.m_XZoom=0.5;dlg.m_YZoom=0.5; if(dlg.DoModal ()!=IDOK)return ;fXZoomRatio=dlg.m_XZoom ; fYZoomRatio=dlg.m_YZoom ;delete dlg;HDIB hNewDIB = NULL;hNewDIB = (HDIB) ZoomDIB(lpDIB, fXZoomRatio, fYZoomRatio);if (hNewDIB != NULL
45、)pDoc->ReplaceHDIB(hNewDIB);pDoc->InitDIBData();pDoc->SetModifiedFlag(TRUE); SetScrollSizes(MM_TEXT, pDoc->GetDocSize();pDoc->UpdateAllViews(NULL);else MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK);:GlobalUnlock(HGLOBAL) pDoc->GetHDIB();缩放实验结果:缩放前的图
46、像 水平和垂直都缩小0.5倍的图像水平和垂直都放大1.5倍的图像3.2.5图像的旋转一般图像的旋转是以图像的中心为原点,旋转一定的角度。旋转后,图像的大小一般会改变。和图像平移一样,既可以把转出显示区域的图像截去,也可以扩大图像范围以显示所有的图像,程序流程图如下:程序开始单击“文件”->“打开”打开一幅图像单击“几何变换”->图像旋转获取旋转角度计算旋转角度的正弦和余弦 计算原图和新图四个角的坐标 否提示用户 程序结束是 程序结束设置脏标记更新视图判断转置是否成功计算旋转后图像实际宽度和高度针对图像每行每列进行操作计算指向新DIB第i行,第j个像素的
47、指针计算该像素在原DIB中的坐标否否提示用户将该像素赋值为255 程序结束是 程序结束设置脏标记更新视图复制平移后的图像直接复制像素判断平移是否成功计算指向原DIB在该坐标下像素的指针判断坐标是否在原图范围内图3.5 图像旋转的程序流程图图像旋转代码:void CImg_TransformView:OnGeomRota() CImg_TransformDoc* pDoc = GetDocument();LPSTR lpDIB;lpDIB = (LPSTR) :GlobalLock(HGLOBAL) pDoc->GetHDIB();MessageBox(&q
48、uot;目前只支持256色位图的缩放!", "系统提示" , MB_ICONINFORMATION | MB_OK);:GlobalUnlock(HGLOBAL) pDoc->GetHDIB();return;float iRotateAngle;CRotateDlg dlg;dlg.m_iRotateAngle=90; if(dlg.DoModal ()!=IDOK)return ;iRotateAngle=dlg.m_iRotateAngle ;delete dlg;HDIB hNewDIB = NULL;hNewDIB = (HDIB)RotateDI
49、B(lpDIB, iRotateAngle);if (hNewDIB != NULL) pDoc->ReplaceHDIB(hNewDIB);pDoc->InitDIBData();pDoc->SetModifiedFlag(TRUE); SetScrollSizes(MM_TEXT, pDoc->GetDocSize();pDoc->UpdateAllViews(NULL);elseMessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK);:GlobalUnloc
50、k(HGLOBAL) pDoc->GetHDIB();旋转实验结果:旋转前图像 旋转65°的图像四、结论与体会本例只针对256级灰度图进行处理。由于本程序首先要实现任意BMP图像的读写,打印,以及剪贴板操作,故用Visual C+创建一个单文档应用程序框架,然后根据BMP图像的结构定义自己的函数库,函数库中包括经常要用到的功能,例如创建DIB对象调色板,返回DIB宽度和高度等,这样在要使用DIB时,只需要对它进行调用就可以了。最后,在对BMP图像各种基础操作实现的基础上,完成经典的图像几何变换功能。包括:1 图像的平移。经典的图像平移有两种算法,一种不会改变图像大小,另一种可以相应扩大图像。本程序采用了第一种算法。为了使图像能按照用户指定的水平平移量和垂直平移量移动,作者首先定义了一个参数设定窗,并在图像平移菜单的事件处理函数中对此对话框进行定义,获取平移量。然后调用图像平移函数,从而实现将图像中所有的点(像素)都按照指定的平移量水平、垂直移动,平移后的图像上的每一点都可以在原图像中找到对应的点。2 图像的镜像。图像的水平镜像操作是将图像的左半部分和右半部分以图像垂直中轴线为中心镜像进行对换;图像的垂直镜像操作是将图像上半部分和下半部分以图像
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- (三模)2025年5月潍坊市高三高考模拟考试历史试卷
- 肺功能康复护理
- 国际学生医疗保险及全面体检服务补充协议
- 跨境电商平台客服质量监控与绩效考核合同
- 电商押金结算服务协议及消费者权益保护规范
- 社区公益项目社区工作者岗位服务协议
- 影视动画主题衍生品生产销售及收益分成合同
- 家庭环保装修工程验收合格责任保证协议
- 房产抵押解除与房屋租赁合同终止协议
- 突发事件公关危机应对与危机干预合同
- GB/T 9065.2-2025液压传动连接软管接头第2部分:24°锥形
- 2023年贵州省粮食储备集团有限公司面向社会公开招聘工作人员15人笔试参考题库附带答案详解
- 道路运输汛期教育培训
- 患者投诉处理与护理试题及答案
- 期中考试考后分析总结主题班会《全员出动寻找消失的分数》
- 公司注册合同协议
- 房地产市场报告 -2025年第一季度青岛写字楼和零售物业市场概况报告
- 2025轨道车司机(技师)重点考试题库及答案(浓缩300题)
- 心功能分级课件
- 行为资产定价理论综述
- 2025年美丽中国第六届全国国家版图知识竞赛测试题库(中小学组)
评论
0/150
提交评论