1、第6章 图像的几何变换第第6 6章章 图像的几何变换图像的几何变换6.1 几何变换基础6.2 图像比例缩放6.3 图像平移6.4 图像镜像6.5 图像旋转6.6 图像复合变换6.7 图像透视变换6.8 应用实例几何畸变的校正第6章 图像的几何变换 6.1 几何变换基础6.1.1 概述图像的几何变换,是指原始图像按照需要产生大小、形状和位置的变化。从图像类型来分,图像的几何变换可以有二维平面图像的几何变换和三维图像的几何变换以及由三维向二维平面投影的变换等。从变换的性质分,图像的几何变换有平移、比例缩放、旋转、反射和错切等基本变换,透视变换等复合变换,以及插值运算等。第6章 图像的几何变换 数字
2、图像是把连续图像在坐标空间和性质空间离散化了的图像。例如,一幅二维数字图像就是把一幅连续的二维(2D)图像在坐标空间XOY和性质空间F都离散化了的图像,它可以用一组2D数组f(x,y)来表示,其中x和y表示2D空间XOY中一个坐标点的位置,f代表图像在点(x,y)的某种性质F的数值。如果所处理的是一幅灰度图,这时f表示灰度值。此时,f、x、y都在整数集合中取值。因此,除了插值运算外,常见的图像几何变换可以通过与之对应的矩阵线性变换来实现。第6章 图像的几何变换由于篇幅所限,本章只讨论2D图像的几何变换。对于2D图像几何变换,由于变换中心在坐标原点的恒等、比例缩放、反射、错切和旋转等各种变换,都
3、可以用22矩阵表示和实现,但是一个22变换矩阵却不能实现2D图像的平移以及绕任意点的比例缩放、反射、错切和旋转等各种变换。因此,为了能够用统一的矩阵线性变换的形式表示和实现这些常见的图像几何变换,就需要引入一种新的坐标齐次坐标。利用齐次坐标进行变换处理,才能实现上述各种2D图像的几何变换。dcbaT第6章 图像的几何变换6.1.2 齐次坐标现设点P0(x0,y0)进行平移后,移到P(x,y),其中x方向的平移量为x,y方向的平移量为y。那么,点P(x,y)的坐标为yyyxxx00如图6-1所示。这个变换用矩阵的形式可以表示为yxyxyx001001第6章 图像的几何变换图6-1 点的平移 第6
4、章 图像的几何变换而平面上点的变换矩阵中没有引入平移常量,无论a、b、c、d取什么值,都不能实现上述的平移变换。因此,需要使用23阶变换矩阵,其形式为dcbaTyxT1001第6章 图像的几何变换此矩阵的第一、二列构成单位矩阵,第三列元素为平移常量。由上述可知,对2D图像进行变换,只需将图像的点集矩阵乘以变换矩阵即可。2D图像对应的点集矩阵是2n阶的,而上式扩展后的变换矩阵是23阶的矩阵,这不符合矩阵相乘时要求前者的列数与后者的行数相等的规则,因此需要在点的坐标列矩阵x yT中引入第三个元素,增加一个附加坐标,扩展为31的列矩阵x y 1T,这样用三维空间点(x y 1)表示二维空间点(x,y
5、),即采用一种特殊的坐标,可以实现平移变换。变换结果为 0PTPyxyyxxyxyx000011001 第6章 图像的几何变换其中符合上述平移后的坐标位置。通常将23阶矩阵扩充为33阶矩阵,以拓宽功能。由此可得平移变换矩阵为yyyxxx001001001yxT第6章 图像的几何变换下面再验证一下点P(x,y)按照33的变换矩阵T平移变换的结果:0PTP11110010010000yxyyxxyxyx从上式可以看出,引入附加坐标后,扩充了矩阵的第3行,并没有使变换结果受到影响。这种用n+1维向量表示n维向量的方法称为齐次坐标表示法第6章 图像的几何变换因此,2D图像中的点坐标(x,y)通常表示成
6、齐次坐标(Hx,Hy,H),其中H表示非零的任意实数,当H1时,称(x,y,1)为点(x,y)的规范化齐次坐标。显然规范化齐次坐标的前两个数是相应二维点的坐标,没有变化,仅在原坐标中增加了H1的附加坐标。由点的齐次坐标(Hx,Hy,H)求点的规范化齐次坐标(x,y,1),可按下式进行:HHxx HHyy 第6章 图像的几何变换齐次坐标的几何意义相当于点(x,y)落在3D空间H1的平面上,如图6-2所示。如果将xOy平面内的三角形abc的各顶点表示成齐次坐标(xi,yi,1)(i=1,2,3)的形式,就变成H1平面内的三角形a1b1c1的各顶点。第6章 图像的几何变换图6-2 齐次坐标的几何意义
7、 第6章 图像的几何变换齐次坐标在2D图像几何变换中的另一个应用是:如某点S(60 000,40 000)在16位计算机上表示,由于大于32767的最大坐标值,需要进行复杂的处理操作。但如果把S的坐标形式变成(Hx,Hy,H)形式的齐次坐标,则情况就不同了。在齐次坐标系中,设H1/2,则S(60 000,40 000)的齐次坐标为(x/2,y/2,1/2),那么所要表示的点变为(30 000,20 000,1/2),此点显然在16位计算机上二进制数所能表示的范围之内。因此,采用齐次坐标,并将变换矩阵改成33阶的形式后,便可实现所有2D图像几何变换的基本变换。第6章 图像的几何变换6.1.3 二
8、维图像几何变换的矩阵利用齐次坐标及改成33阶形式的变换矩阵T,实现2D图像几何变换的基本变换的一般过程是:将2n阶的二维点集矩阵x0i y0iT2n表示成齐次坐标x0i y0i 1T3n的形式,然后乘以相应的变换矩阵即可,即 变换后的点集矩阵=变换矩阵T变换前的点集矩阵(图像上各点的新齐次坐标)(图像上各点的原齐次坐标)第6章 图像的几何变换设变换矩阵T为smlqdcpbaT则上述变换可以用公式表示为nnnHHHHyHyHyHxHxHx32121Tnnnyyyxxx32121111T=第6章 图像的几何变换图像上各点的新齐次坐标规范化后的点集矩阵为nnnyyyxxx32121111引入齐次坐标
9、后,表示2D图像几何变换的33阶矩阵的功能就完善了,我们可以用它完成2D图像的各种几何变换。下面我们讨论33阶变换矩阵中各元素在变换中的功能。几何变换的33矩阵的一般形式为smlqdcpbaT第6章 图像的几何变换33阶的矩阵T可以分成四个子矩阵。其中,这个22阶子矩阵可使图像实现变换中心在坐标原点的恒等、比例、反射(或镜像)、错切和旋转变换。l m这一行矩阵可以使图像实现平移变换。p qT这一列矩阵可以使图像实现透视变换,但当p=0,q=0时它无透视作用。s这一元素可以使图像实现全比例变换。例如,将图像进行全比例变换,即22dcba第6章 图像的几何变换s000100011100iiiiyx
10、yx将齐次坐标规范化后,x0i/s y0i/s 1T=xi yi 1T。由此可见,当s1时,图像按比例缩小;当0s1时,整个图像按比例放大;当s1时,图像大小不变。第6章 图像的几何变换6.2 图像比例缩放6.2.1 图像比例缩放变换图像比例缩放是指将给定的图像在x轴方向按比例缩放fx倍,在y轴方向按比例缩放fy倍,从而获得一幅新的图像。如果fx=fy,即在x轴方向和y轴方向缩放的比率相同,称这样的比例缩放为图像的全比例缩放。如果fxfy,图像的比例缩放会改变原始图像像素间的相对位置,产生几何畸变。设原图像中的点P(x0,y0)比例缩放后,在新图像中的对应点为P(x,y),则P(x0,y0)和
11、P(x,y)之间的对应关系如图6-3所示。第6章 图像的几何变换图6-3 比例缩放 第6章 图像的几何变换比例缩放前后两点P(x0,y0)、P(x,y)之间的关系用矩阵形式可以表示为11000000100yxffyxyx(61)公式(6-1)的逆运算为1100010001100yxffyxyx第6章 图像的几何变换即yxfyyfxx00比例缩放所产生的图像中的像素可能在原图像中找不到相应的像素点,需要进行近似处理。插值处理常用的方法有两种,一种是直接赋值为和它最相近的像素值,另一种是通过一些插值算法来计算相应的像素值。前一种方法计算简单,但会出现马赛克现象;后者处理效果要好些,但是运算量也相应
12、增加。在下面的算法中我们直接采用了前一种方法。实际上,这也是一种插值算法,称为最邻近插值(Nearest Neighbor Interpolation)或者最近邻域法。第6章 图像的几何变换下面首先讨论图像的比例缩小。最简单的比例缩小是当fx=fy=1/2 时,图像被缩到1/4大小,缩小后图像中的(0,0)像素对应于原图像中的(0,0)像素;(0,1)像素对应于原图像中的(0,2)像素;(1,0)像素对应于原图像中的(2,0)像素,依此类推。图像缩小之后,因为承载的信息量小了,所以画布可相应缩小。此时,只需在原图像基础上,每行隔一个像素取一点,每隔一行进行操作。即取原图的偶(奇)数行和偶(奇)
13、数列构成新的图像,如图6-4所示。如果图像按任意比例缩小,则需要计算选择的行和列。第6章 图像的几何变换图6-4 图像缩小到1/4 第6章 图像的几何变换如果MN大小的旧图像F(x,y)缩小为kMkN大小(k1)的新图像I(x,y),则I(x,y)=F(int(cx),int(cy)式中,c=1/k。由此公式可以构造出新图像,如图6-5所示。第6章 图像的几何变换图6-5 图像按任意比例缩小 第6章 图像的几何变换当fxfy(fx,fy0)时,图像不按比例缩小,这种操作因为在x方向和y方向的缩小比例不同,一定会带来图像的几何畸变。图像不按比例缩小的方法是:如果MN大小的旧图像F(x,y)缩小为
14、k1Mk2N大小,(k11,k20)时,图像在x方向和y方向按不同比例放大,此时,这种操作由于x方向和y方向的放大倍数不同,会产生图像的几何畸变。放大的方法是将原图像的一个像素添到新图像的一个k1k2的子块中去。为了提高几何变换后的图像质量,常常采用线性插值法。该方法的原理是:当求出的分数地址与像素点不一致时,求出周围四个像素点的距离比,根据该比率,由四个邻域的像素灰度值进行双线性插值,如图6-10所示。第6章 图像的几何变换图6-9 按最近邻域法放大5倍的图像 第6章 图像的几何变换图6-10 线性插值法示意图 第6章 图像的几何变换简化后的灰度值计算式如下:)1,1()1,()1(),1(
15、),()1()1(),(yxfpyxfpqyxfpyxfpqyxg(62)式中:g(x,y)为插值后坐标(x,y)处的灰度值;f(x,y)为插值前坐标(x,y)处的灰度值;x,y 分别为不大于x、y的整数。关于这个问题的详细算法及其实现,读者可以参考有关参考文献。第6章 图像的几何变换6.2.2 比例缩放的实现按照公式(6-1)以及最近邻域法,可以编写一个实现图像比例缩放的函数ZoomImage(),从而实现图像的比例缩放,如图6-11所示。第6章 图像的几何变换图6-11 图像的比例缩放 第6章 图像的几何变换下面给出这个函数的结构和主要算法。/*/函数名称:BOOL ZoomImage()
16、/基本功能:本函数对传入的CDibObject对象中的图像进行缩放操作。如果进行此调整之前/没有指定一个CDibObject对象指针,则必须在调整时加以指定/参数说明:float fXZoomRatio X轴方向缩放比率 float fYZoomRatio Y轴方向缩放比率/BOOL bBilinear TRUE为双线性插值,FALSE为最邻近插值/CDibObject*pDibObject,默认为NULL第6章 图像的几何变换/返回值:BOOL,成功返回TRUE,失败返回FALSE/*BOOL CGeoTrans:ZoomImage(float fXZoomRatio,float fYZoo
17、mRatio,BOOL bBilinear,CDibObject*pDibObject)/定义变量,获得原图像指针及其图像信息,计算新图/像的大小,为新图像分配内存等及用255(白色)填充新 /图像数据区,用原图像调色板填充新图像调色板等 /针对图像每行进行操作第6章 图像的几何变换for(y=0;y nNewHeight;y+)/指向新图像第y行 /注意此处宽度和高度是新图像的宽度和高度 pNewTemp=pNewBits;pNewTemp+=(nNewHeight-1-y)*nNewWidthBytes;/针对图像每列进行操作 for(x=0;x=0)&(x0=0)&(y0GetDib()
18、;:GlobalFree(m_pDibObject-GetDib();:GlobalUnlock(hNewDib);/将新图像设置为当前图像 m_pDibObject-SetDib(hNewDib);m_pDibObject-ProcessImageHeader();return TRUE;第6章 图像的几何变换6.3 图像平移6.3.1 图像平移变换图像的平移是指将一幅图像上的所有点都按照给定的偏移量在水平方向沿x轴、在垂直方向沿y轴移动,平移后的图像与原图像相同,如图6-12所示。图像的平移是图像几何变换中最简单的变换之一。第6章 图像的几何变换图6-12 图像的平移 第6章 图像的几何变
19、换设点P0(x0,y0)进行平移后,移到P(x,y),其中x方向的平移量为x,y方向的平移量为y。那么,点P(x,y)的坐标为yyyxxx00利用齐次坐标,变换前后图像上的点P0(x0,y0)和P(x,y)之间的关系可以用如下的矩阵变换表示:11001001100yxyxyx(63)第6章 图像的几何变换对变换矩阵求逆,可以得到式(6-3)的逆变换:11001001100yxyxyx即yyyxxx00第6章 图像的几何变换这样,平移后的图像上的每一点都可以在原图像中找到对应的点。例如,对于新图像中的(0,0)像素,代入上面的方程组,可以求出对应原图像中的像素(-x,-y)。如果x或y大于0,则
20、点(-x,-y)不在原图像中。对于不在原图像中的点,可以直接将它的像素值统一设置为0或者255(对于灰度图就是黑色或白色)。同样,若有像素点不在原图像中,也就说明原图像中有点被移出显示区域。如果不想丢失被移出的部分图像,可以将新生成的图像宽度增大|x|,高度增大|y|。图6-13是平移前的图像,图6-14是水平和垂直方向都平移50个像素后的图像,图6-15是平移扩大原图像后的图像。第6章 图像的几何变换图6-13 平移前的图像 第6章 图像的几何变换图6-14 平移后的图像 第6章 图像的几何变换图6-15 平移扩大后的图像 第6章 图像的几何变换6.3.2 图像平移的算法按照上述理论,可以容
21、易地用Visual C+来实现图像的平移。下面介绍灰度图像的平移。因为灰度图像每个像素位数正好是8位,即1个字节,因而在进行图像处理时可以不用考虑拼凑字节的问题。而且由于灰度图调色板的特殊性,进行图像处理时可不必考虑调色板问题,以便将重点放在算法本身。第6章 图像的几何变换由上述分析,可以得到实现图像平移的算法如下。/*/函数名称:BOOL TranslationPixel()/基本功能:本函数对传入的CDibObject对象中的图像/进行平移操作。如果进行此调整之前没有指定一个/CDibObject对象指针,则必须在调整时加以指定/参数说明:long lXOffset X轴平移量(像素数);
22、/long lYOffset Y轴平移量(像素数)CDibObject/*pDibObject,默认为NULL第6章 图像的几何变换/返回值:BOOL,成功返回TRUE,失败返回FALSE/注意:该函数用来水平移动DIB图像。函数不会改变/图像的大小,移出部分的图像将被截去,空白部分用/白色填充。该函数逐点移动图像/*BOOL CGeoTrans:TranslationPixel(long lXOffset,long lYOffset,CDibObject*pDibObject)/定义变量,获得原图像指针及其图像信息,计算新 /图像的大小,为新图像分配内存等及用255(白色)/填充新图像数据区
23、,用原图像调色板填充新图像调 /色板等由图像位数确定的移动字节数nMovedBits,/对于灰度图像有nMovedBits=1 /针对图像每行进行操作第6章 图像的几何变换 for(y=0;y nHeight;y+)pNewTemp=pNewBits;/注意由于DIB中图像第一行其实保存在最后一 /行的位置 pNewTemp+=(nHeight-1-y)*nWidthBytes;/针对图像每列进行操作 for(x=0;x=0)&(x0=0)&(y0 GetDib();return TRUE;由于平移前后的图像相同,而且图像上的像素是连续放置的,所以图像的平移也可以通过直接逐行复制图像来实现。有
24、兴趣的读者,请参阅相关参考文献。第6章 图像的几何变换 6.4 图像镜像6.4.1 图像镜像变换图像的镜像(Mirror)变换不改变图像的形状。镜像变换分为两种:一种是水平镜像,另外一种是垂直镜像。图像的水平镜像操作是将图像左半部分和右半部分以图像垂直中轴线为中心进行镜像对换;图像的垂直镜像操作是将图像上半部分和下半部分以图像水平中轴线为中心进行镜像对换,如图6-16所示。但是为了编程与实现方便,往往对水平镜像在x方向作一个平移(图像宽度),对垂直镜像在y方向作一个平移(图像高度)。第6章 图像的几何变换图6-16 图像的镜像 第6章 图像的几何变换图像的镜像变换也可以用矩阵变换表示。设点P0
25、(x0,y0)进行镜像后的对应点为P(x,y),图像高度为fHeight,宽度为fWidth,原图像中P0(x0,y0)经过水平镜像后坐标将变为(fWidthx0,y0),其矩阵表达式为110001001100yxfWidthyx第6章 图像的几何变换它的逆运算矩阵表达式为110001001100yxfWidthyx即 yyxfWidthx00第6章 图像的几何变换同样,P0(x0,y0)经过垂直镜像后坐标将变为(x0,fHeighty0),其矩阵表达式为110010001100yxfHeightyx第6章 图像的几何变换其逆运算矩阵表达式为110010001100yxfHeightyx即 y
26、fWidthyxx00第6章 图像的几何变换6.4.2 图像镜像的算法按照上面的变换公式(6-4)和(6-5),可以简单地实现图像的水平和垂直镜像操作,读者可以参照6.3.2节中的平移算法,写出与公式(6-4)和(6-5)对应的算法。和图像平移一样,在垂直镜像中也可以利用位图存储的连续性整行复制图像。下面将介绍该方法的算法。其主要算法如下,bDirection为真时表示水平镜像,否则为垂直镜像。第6章 图像的几何变换/*/函数名称:BOOL Mirror()/基本功能:本函数对传入的CDibObject对象中的图像进行镜像操作。/如果进行此调整之前没有指定一个CDibObject对象指针,则必
27、须在调/整时加以指定/参数说明:BOOL bDirection 镜像的方向,TRUE表示水平镜像,FALSE表示垂直镜像;/CDibObject*pDibObject,默认为NULL/返 回 值:BOOL,成功返回TRUE,失败返回FALSE/*BOOL CGeoTrans:Mirror(BOOL bDirection,CDibObject*pDibObject)第6章 图像的几何变换 /使用传入的CDibObject对象,获得图像宽度、高度,/定义变量,获得原图像指针及其图像信息,计算新 /图像的大小,为新图像分配内存等及用255(白色)填 /充新图像数据区,由图像位数确定移动的字节数等 /
28、判断镜像方式 if(bDirection)第6章 图像的几何变换 /水平镜像 /垂直中轴坐标 int nMiddleX=nWidth/2;/针对图像每行进行操作 for(y=0;y nHeight;y+)/指向图像的倒数第y行 pOldTemp=pOldBits;pOldTemp+=y*nWidthBytes;第6章 图像的几何变换 pNewTemp=pNewBits;pNewTemp+=y*nWidthBytes;/针对每行图像左半部分进行操作 for(x=0;x=nMiddleX;x+)/将原图像第x个像素复制到新图像倒数 /第x个像素 pTemp1=pOldTemp+x*nMovedBi
29、ts;pTemp2=pNewTemp+(nWidth-1-x)*nMovedBits;第6章 图像的几何变换 memcpy(pTemp2,pTemp1,nMovedBits);/将原图像倒数第x个像素复制到新图像 /第x个像素 pTemp1=pOldTemp+(nWidth-1-x)*nMovedBits;pTemp2=pNewTemp+x*nMovedBits;memcpy(pTemp2,pTemp1,nMovedBits);第6章 图像的几何变换 else /垂直镜像 /水平中轴坐标 int nMiddleY=nHeight/2;/针对上半图像进行操作 for(y=0;y GetDib()
30、;return TRUE;镜像前的原始图像如图6-17所示,图6-18是水平镜像的结果,垂直镜像的结果如图6-19所示。第6章 图像的几何变换图6-17 镜像前的图像 第6章 图像的几何变换图6-18 水平镜像 第6章 图像的几何变换图6-19 垂直镜像 第6章 图像的几何变换6.5 图像旋转6.5.1 图像旋转变换本节介绍一种相对复杂的几何变换图像旋转。一般来说,图像旋转是指以图像的中心为原点,将图像上的所有像素都旋转一个相同的角度。图像的旋转变换是图像的位置变换,但旋转后,图像的大小一般会改变。和图像平移一样,在图像旋转变换中既可以把转出显示区域的图像截去,也可以扩大图像范围以显示所有的图
31、像,如图6-20和图6-21所示。第6章 图像的几何变换图6-20 旋转前的图像 第6章 图像的几何变换图6-21 旋转后的图像(扩大图像、转出部分被截)第6章 图像的几何变换同样,图像的旋转变换也可以用矩阵变换表示。设点P0(x0,y0)旋转角后的对应点为P(x,y),如图6-22所示。那么,旋转前后点P0(x0,y0)、P(x,y)的坐标分别是:sincos00ryrxcossinsincoscossin)sin(sincossinsincoscos)cos(0000yxrrryyxrrrx第6章 图像的几何变换写成矩阵表达式为11000cossin0sincos100yxyx(66)其逆
32、运算为1 1000cossin0sincos100yxyx第6章 图像的几何变换图6-22 图像旋转角 第6章 图像的几何变换利用变换式(6-6)可以确定旋转后图像上的像素。例如,对图6-23所示大小为33的图像,当=30时公式(6-6)为 0000866.05.05.0866.0yxyyxx变换后x、y可能取的最小和最大值分别为xmin=0.866+0.53=2.366,xmax=0.8663+0.5=3.098ymin=-0.53+0.866=-0.634,ymax=-0.5+0.8663=2.098可见,变换后的像素位置超出了原图像区域。第6章 图像的几何变换图6-23 图像旋转角 第6
33、章 图像的几何变换利用变换式(6-6)进行图像旋转时需要注意如下两点:(1)图像旋转之前,为了避免信息的丢失,一定要平移坐标,具体的做法有如图6-24所示的两种方法。(2)图像旋转之后,会出现许多的空洞点,如图6-23所示。对这些空洞点必须进行填充处理,否则画面效果不好。一般也称这种操作为插值处理。最简单的方法是行插值方法或列插值方法:找出当前行的最小和最大的非白点的坐标,记作(i,k1)、(i,k2)。在(k1,k2)范围内进行插值,插值的方法是:空点的像素值等于前一点的像素值。同样的操作重复到所有行。经过如上的插值处理之后,图像效果就变得自然了,如图6-25所示。列插值方法与此类同,请读者
34、自己给出。第6章 图像的几何变换图6-24 图像旋转之前进行的平移 第6章 图像的几何变换图6-25 图6-23中的图像处理后的效果 第6章 图像的几何变换上述所讨论的旋转是绕坐标轴原点(0,0)进行的。如果图像旋转绕一个指定点(a,b)进行,则先要将坐标系平移到该点,再进行旋转,然后将旋转后的图像平移回原来的坐标原点。这实际上是图像的复合变换,将在图像的复合变换中讨论。第6章 图像的几何变换6.5.2 图像旋转的实现按照上述理论,用Visual C+编程可以实现图像的旋转。下面给出灰度图像的旋转算法。由式(6-6)以及当产生空点时使用双线性插值方法,可以编写一个实现图像旋转的函数Rotate
35、()。下面给出这个函数的结构和主要算法。第6章 图像的几何变换/*/函数名称:BOOL Rotate()/基本功能:本函数对传入的CDibObject对象中的图像进行/旋转操作。如果进行此调整之前没有指定一个CDibObject/对象指针,则必须在调整时加以指定/参数说明:int iRotateAngle 旋转的角度(0360度)/BOOL bBilinear TRUE为双线性插值,/FALSE为最邻近插值/CDibObject*pDibObject,默认为NULL/返回值:BOOL,成功返回TRUE,失败返回FALSE第6章 图像的几何变换/注意:该函数用来以图像中心为中心旋转图像,调用该函
36、数会自动扩/大图像以显示所有的像素。函数中采用最邻近插值算法进行插值/*BOOL CGeoTrans:Rotate(int nRotateAngle,BOOL bBilinear,CDibObject*pDibObject)/获得图像宽度和高度:nOldWidth和nOldHeight /定义旋转角度(弧度)及其正弦和余弦值 /定义表示原图像四个角的坐标、旋转后四个角的坐标(以图像中心 /为坐标系原点)的变量将旋转角度从度转换到弧度,并计算旋转角 /度的正弦、余弦值第6章 图像的几何变换 fSina=(float)sin(double)fRotateAngle);/计算原图像及新图像的四个角的
37、坐标(以图像中心为 /坐标系原点)计算新图像四个角的坐标(以图像中心为 /坐标系原点)fDstX1=fCosa*fSrcX1+fSina*fSrcY1;fDstY1=-fSina*fSrcX1+fCosa*fSrcY1;fDstX2=fCosa*fSrcX2+fSina*fSrcY2;fDstY2=-fSina*fSrcX2+fCosa*fSrcY2;fDstX3=fCosa*fSrcX3+fSina*fSrcY3;fDstY3=-fSina*fSrcX3+fCosa*fSrcY3;第6章 图像的几何变换 fDstX4=fCosa*fSrcX4+fSina*fSrcY4;fDstY4=-fSi
38、na*fSrcX4+fCosa*fSrcY4;/计算旋转后图像的实际宽度 int nNewWidth =(long)(max(fabs(fDstX4-fDstX1),fabs(fDstX3-fDstX2)+0.5);/计算旋转后的图像高度 int nNewHeight=(long)(max(fabs(fDstY4-fDstY1),fabs(fDstY3-fDstY2)+0.5);/两个常数第6章 图像的几何变换 f1=(float)(-0.5*(nNewWidth-1)*fCosa-0.5*(nNewHeight-1)*fSina+0.5*(nOldWidth -1);f2=(float)(0
39、.5*(nNewWidth-1)*fSina-0.5*(nNewHeight-1)*fCosa+0.5*(nOldHeight-1);/获取指向原图像的指针,为旋转后所得图像分配内存并用 /255(白色)填充新图像数据区由图像位数确定的移动字节数 /nMovedBits针对图像每行进行操作 for(y=0;y nNewHeight;y+)第6章 图像的几何变换 /指向新图像第y行 /注意此处宽度和高度是新图像的宽度和高度 pNewTemp=pNewBits;pNewTemp+=(nNewHeight-1-y)*nNewWidthBytes;/针对图像每列进行操作 for(x=0;x=0)&(x
40、0=0)&(y0 nOldHeight)/用双线性插值 if(bBilinear)第6章 图像的几何变换 unsigned char*pTemp=Interpolation (nOldWidth,nOldHeight,(float)x0,(float)y0,nOldWidthBytes,nMovedBits,pOldBits);/复制像素 memcpy(pNewTemp,pTemp,nMovedBits);delete pTemp;else 第6章 图像的几何变换 /指向原图像第y0行,第x0个像素 /注意此处宽度和高度应该互换 pOldTemp=pOldBits;pOldTemp+=(nOl
41、dHeight-1-y0)*nOldWidthBytes;pOldTemp+=x0*nMovedBits;/复制像素 memcpy(pNewTemp,pOldTemp,nMovedBits);第6章 图像的几何变换 pNewTemp+=nMovedBits;/将内存解锁和将不再使用的内存释放,将新图像 /设置为当前图像 return TRUE;第6章 图像的几何变换旋转前的原始图像如图6-26所示,图6-27是该图像旋转15并进行双线性插值处理后的结果。如果将旋转前后的图像放大,从中可以看出旋转前后图像上像素之间的变化,如图6-28和图6-29所示。第6章 图像的几何变换图6-26 旋转前的图
42、像 第6章 图像的几何变换图6-27 旋转15并进行插值处理的图像 第6章 图像的几何变换图6-28 被放大的旋转前图像 第6章 图像的几何变换图6-29 旋转30并进行插值处理的放大图像 第6章 图像的几何变换 6.6 图像复合变换6.6.1 图像的复合变换图像的复合变换也称为级联变换,是对给定的图像连续施行若干次如前所述的平移、镜像、比例缩放、旋转等基本变换后所完成的变换。利用齐次坐标,对给定的图像依次按一定顺序连续施行若干次基本变换,其变换的矩阵仍然可以用33阶的矩阵表示,而且从数学上可以证明,复合变换的矩阵等于基本变换的矩阵按顺序依次相乘得到的矩阵乘积。设对给定的图像依次进行了基本变换
43、F1,F2,FN,它们的变换矩阵分别为T1,T2,TN,按照式(6-1)(6-6)的表示形式,图像的复合变换矩阵T可以表示为:T=TNTN1T1。第6章 图像的几何变换常见的复合变换有两类:一类是同一种基本变换依次连续进行若干次,例如复合平移、复合比例缩放、复合旋转等;另一类是其中含有不同类型的基本变换,例如图像的转置、绕任意点的比例缩放、绕任意点的旋转等。下面首先讨论第一类图像复合变换。第6章 图像的几何变换1.复合平移设某个图像先平移到新的位置P1(x1,y1)后,再将图像平移到P2(x2,y2)的位置,则复合平移变换的矩阵为1001001100100110010012121221121y
44、yxxyxyxTTT由此可见,尽管按一定顺序进行一些平移,用到矩阵的乘法,但最后合成的复合平移矩阵,只需对平移常量作加法运算。第6章 图像的几何变换2.复合比例同样,对给定图像连续进行比例交换,最后合成的复合比例变换矩阵,只要对比例常量作乘法运算即可。复合比例变换矩阵如下:1000000100000010000002121221121ddaadadaTTT(68)第6章 图像的几何变换3.复合旋转类似地,对给定图像连续进行旋转变换,最后得到的旋转变换矩阵等于两次旋转角度的和,复合旋转变换矩阵如下:1000cossin0sincos1000cossin0sincos1111222221TTT10
45、00)cos()sin(0)sin()cos(21212121(69)第6章 图像的几何变换上述的图像变换都是相对原点(图像中心)作平移、比例缩放、旋转等变换,如果要相对某一个参考点作变换,则要使用含有不同种基本变换的图像复合变换。不同的复合变换,其变换过程不同,但是无论它的变换过程有多么复杂,都可以分解成一系列基本变换。相应地,使用齐次坐标后,图像复合变换的矩阵由一系列图像基本几何变换矩阵依次相乘而得到。下面通过一个例子讨论含有不同种基本变换的图像复合变换。第6章 图像的几何变换从6.2和6.5节的讨论中可以看出,在进行图像的比例缩放、旋转变换时,整个变换过程由两部分组成,即需要两个独立的算
46、法。首先,需要一个算法来完成几何变换本身,用它描述每个像素如何从其初始位置变换到最终位置,即每个像素的变换;同时,还需要一个用于灰度级插值的算法,这是因为,在一般情况下,原始(输入)图像的位置坐标(x,y)为整数,而变换后(输出)图像的位置坐标为非整数,即产生“空穴”,反过来也是如此。因此,一般地,在进行图像的几何变换时,除了要进行其本身的几何变换外,还要进行灰度级插值的处理。第6章 图像的几何变换实现图像的灰度级插值处理时,可采用如下两种方法。第一,可以把几何变换想象成将输入图像的灰度一个像素一个像素地转移到输出图像中。如果一个输入像素被映射到四个输出像素之间的位置,则其灰度值就按插值算法在
47、四个输出像素之间进行分配。把这种灰度级插值处理称为像素移交(Pixel Carryover)或称为向前映射法,如图6-30所示。第6章 图像的几何变换图6-30 灰度级插值处理(像素变换)第6章 图像的几何变换另一种更有效的灰度级插值处理方法是像素填充(Pixel Filling)或称为向后映射法。在这种算法中,输出像素一次一个地映射回到原始(输入)图像中,以便确定其灰度级。如果一个输出像素被映射到四个输出像素之间,则其灰度值由灰度级插值决定,如图6-30所示,向后空间变换是向前变换的逆。像素填充法对一般的应用更为切实可行。第6章 图像的几何变换在像素填充法中,变换后(输出)图像的像素通常被映
48、射到原始(输入)图像中的非整数位置,即位于四个输入像素之间。因此,为了决定与该位置相对应的灰度值,必须进行插值运算。最简单的插值方法是零阶插值或称为最近邻插值,也叫最近邻域法,参见本书6.2节。一阶插值(或称双线性插值法)和零阶插值法相比可产生更加满意的效果,只是程序稍复杂、运行时间稍长一些。它的原理如图6-10和图6-31所示,插值计算公式参见6.2.1中的公式(6-2)。由于篇幅所限,双线性插值公式的推导在此从略,有兴趣的读者请参考书后的参考文献。第6章 图像的几何变换图6-31 双线性插值 第6章 图像的几何变换在这里还要说明一点,为了提高双线性插值的速度,双线性插值也可以分解为三个线性
49、插值来实现,公式如下:)0,()1,()0,(),()1,0()1,1()1,0()1,()0,0()0,1()0,0()0,(xfxfyxfyxfffxfxfffxfxf(610)因为式(6-2)需要用到4次乘法、8次加(或减)法运算,而式(6-10)表示的第二种方法只需要3次乘法和6次加(减)法,所以几何变换程序一般选择后者。从图6-31也可以看出双线性插值与最近邻插值的区别。第6章 图像的几何变换在几何运算中,双线性灰度插值的平滑作用可能会使图像的细节产生退化,尤其在图像放大处理时影响更为明显。而在其他应用中,双线性插值的斜率不连续性会产生不希望得到的结果。这两种情况都可以通过高阶插值得
50、到修正,当然这需要增加计算量。使用高阶插值函数的例子有:三次样条、Legendre中心函数和sin(x)/函数(即sin(x)函数)。高阶插值常用卷积来实现,请读者参考书后参考文献。第6章 图像的几何变换6.6.2 图像复合变换示例在6.5节中我们所讨论的旋转变换是绕坐标轴原点(0,0)进行的。但是如果图像旋转是绕一个指定点(a,b)进行的,则先要将坐标系平移到该点,再进行旋转,然后将旋转后的图像平移回原来的坐标原点。下面我们推导这个图像复合变换的公式。首先推导坐标系平移的转换公式。如图6-32所示,将坐标系平移到坐标系处,其中坐标系的原点在坐标系中的坐标为(a,b)。第6章 图像的几何变换图