vc实现图像的基本几何变换
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Vc 实现图像的基本几何变换
图像的几何变换,通常包括图像的平移、图像的镜像变换、图像的转置、图像的缩放和图像的旋转等。
程序基本框架如下:
图1.1 程序基本框架图
1.1 图像的平移
图像的平移是几何变换中最简单的变换之一。
1.1.1 理论基础
图像平移就是将图像中所有的点都按照指定的平移量水平、垂直移动。设(x0,y0)为原图像上的一点,图像水平平移量为tx ,垂直平移量为ty ,则平移后点(x0,y0)坐标将变为(x1,y1)。
显然(x0,y0)和(x1,y1)的关系如下:
⎩⎨
⎧+=
+=ty
y y tx x x 0101
用矩阵表示如下:
⎥⎥⎥⎦
⎤⎢⎢⎢⎣⎡⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡=⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡1001001001111y x ty tx y x
对该矩阵求逆,可以得到逆变换:
⎥⎥
⎥⎦
⎤
⎢⎢⎢⎣⎡⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡--=⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡1111001001100y x ty tx y x 即⎩⎨⎧-=-=
ty
y y tx x x 1010
这样,平移后的图像上的每一点都可以在原图像中找到对应的点。例如,
对于新图中的(0,0)像素,代入上面的方程组,可以求出对应原图中的像素(-tx ,-ty )。如果tx 或ty 大于0,则(- tx ,- ty )不在原图中。对于不在原图中的点,可以直接将它的像素值统一设置为0或则255(对于灰度图就是黑色或白色)。同样,若有点不在原图中,也就说明原图中有点被移出显示区域。如果不想丢失被移出的部分图像,可以将新生成的图像宽度扩大|tx |,高度扩大| ty |。
1.1.2 Visual C++编程实现
有了上面的理论基础,可以十分容易的用Visual C++来实现图像的平移。在这里,只介绍灰度图像的平移,因为灰度图像每个像素位数正好是8位,即1个字节,这样,在进行图像处理时,可以不必考虑拼凑字节的问题。而且由于灰度图调色板的特殊性,进行灰度图像处理时,不必考虑调色板的问题。根据上面的公式可以得到图像的平移程序流程图:
图1.2 图像平移程序流程图
由上面的程序流程图可以得到如下算法:
//每行
for(i=0;i { //每列 for(j=0;j { lpDst=(char*)lpNewDIBBits+lLineBytes*(lHeight-1-i)+j; //计算该像素在原DIB中的坐标 i0=i-lXOffset; j0=j-lYOffset; //判断是否在原图范围内 if(j0>=0)&&(j0 { //指向原DIB第i0行,第j0个像素的指针 //同样要注意DIB上下倒置的问题 lpSrc=(char*)lpDIBBits+lLineBytes*(lHeight-1-i0)+j0; //复制像素 *lpDst=*lpSrc; } else { *((unsigned char*)lpDst)=255; //对于原图中没有的像素,直接 赋值为255 } } } 由于每行像素是连续放置的,可以直接逐行地来复制图像。首先计算移出后可视的区域。 对于x轴方向, 当tx ≤-width时,图像完全移出了屏幕,不用做任何处理; 当-width< tx ≤ 0时,图像区域的x范围从0到width-tx,对应原图的范围从tx到width; 当0〈tx〈width时,图像区域的x范围从tx到width,对应原图的范围从0到width-tx; 当tx ≥width时,图像完全移出了屏幕,不用做任何处理; 对于y轴方向, 当ty ≤-height时,图像完全移出了屏幕,不用做任何处理; 当-height〈ty ≤0时,图像区域的y范围从0到height- ty,对应原图的范围从ty到height; 当0〈ty〈height时,图像区域的y范围从ty到height,对应原图的范围从0到height-ty; 当ty ≥height时,图像完全移出了屏幕,不用做任何处理; 当计算出经移动而可视的区域后,就可以利用位图存储的连续性,即同一 行的像素在内存中是相邻的这一规则进行计算。利用memcpy函数,从(x0,y0)点开始,一次可以拷贝一整行(宽度为x1-x0),然后将内存指针移到(x0,y0+1)处,拷贝下一行。这样拷贝到(y1-y0)行就完成了全部操作,避免了单个像素的计算,从而提高了效率。 按照上面的描述,现在可以构造自己的图像几何变换函数库了。首先来完成图像的平移函数。图像的平移函数操作不需要改变DIB的调色板和文件头,只要把指向DIB像素起始位置的指针和DIB高宽传递给子函数就可以完成平移工作。 下面以图像平移为例说明图像处理的简易流程图: 图1.3 图像平移处理的简易流程图 下面是程序进行平移时的界面: 图像平移后的结果为: 1.2 图像的镜像变换 图像的镜像变换分为两种:一种是水平镜像,另外一种是垂直镜像。图像的水平镜像操作是将图像的左半部分和右半部分以图像垂直中轴线为中心镜像进行对换;图像的垂直镜像操作是将图像上半部分和下半部分以图像水平中轴线为中心镜像进行对换。 1.2.1 理论基础 设图像高度为lHeight ,宽度为lWidth ,原图中(x0,y0)经过水平镜像后坐标将变为(lWidth-x0,y0),其矩阵表达式为: ⎥⎥⎥⎦ ⎤ ⎢⎢⎢⎣⎡⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡-=⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡10010001001111x y lWidth y x 逆运算矩阵表达式为: ⎥⎥⎥⎦ ⎤ ⎢⎢⎢⎣⎡⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡-=⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡11110001001100y x lWidth y x 即⎩⎨⎧=-=101 0y y x lWidth x 同样,(x0,y0)经过垂直镜像后坐标将变为(x0,lHeight-y0),其矩阵表 达式为: ⎥⎥⎥⎦ ⎤⎢⎢⎢⎣⎡⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡-=⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡1001001000 1111y x lHeight y x 逆运算矩阵表达式为: ⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡-=⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡11110 01000 1100y x lHeight y x 即⎩⎨⎧-== 1 010y lHeight y x x 1.2.2 Visual C++编程实现 按照上面的变换公式,可以非常简单的实现图像的水平和垂直镜像操作。 下图是镜像操作的程序流程图: