第四章 几何变换
一、缩小
1. 问题
缩小:幅面减小,像素减少,图像等比例缩小全部处于幅面中
裁剪:幅面减小,像素减少,图像不变,局部处于幅面中,多出部分丢弃。 宽度与高度方向的缩小比例可以不同。
图像缩小的参数:dWidth——缩小后的图像宽度,有dWidth<=Width
dHight——缩小后的图像高度,有dHeight<=Height
2. 方法
抽点法——采样法 平均法 3. 采样法程序
void Reduce(int dWidth, int dHeight,(BYTE*) &dImageData) { }
int dWidthBytes = (int)((dWidth*3+3)/4)*4; int dImageSize = dWidthBytes*dHeight; dImageData = malloc(dImageSize); float ws = (float)Width/dWidth; float hs = (float)Height/dHeight; int i,j,k,di,dj,dk;
for(di=0;di k = WidthBytes*i + 3*j; //原图中像素地址 memcpy(dImageData+dk, ImageData+k, 3); dk+=3; //新图中像素地址 i = di*hs+0.5; //原图中的行 } 二、放大 图像放大:幅面增大,像素增多,图像等比例放大,占满整个幅面 画布放大:幅面增大,图像不变,图像周围为空白画面。 《数字图像处理》几何变换 2 图像放大的参数:dWidth——放大后的图像宽度,有dWidth>=Width dHight——放大后的图像高度,有dHeight>=Height 放大处理方法: 像素放大法——采样法 插值法——线性插值,二次插值,三次插值 放大采样法的处理程序与缩小的采样法程序完全相同。 双向线性插值方法例: 设ws=Width/dWidth=0.7,hs=0.7 则新图像中的点(6,8)对应于原图像中的位置为(4.2,5.6) 当采用采样法时,将取离该位置最近的点(4,6)填入新图像的(6,8)点。 当采用双向线性插值时,则取该位置周围的四个点,插值计算该点的值。如下图: V1(4,5)V12V0.2(4.2,5.6)V2(4,6)0.6V3(5,5)V4V34(5,6) 则有:V12=V1*(1-0.6)+V2*0.6 V34=V3*(1-0.6)+V4*0.6 V=V12*(1-0.2)+V34*0.2 =V1*(1-0.6)*( 1-0.2)+V2*0.6*( 1-0.2) +V3*(1-0.6)*0.2+V4*0.6*0.2 =V1*0.32+V2*0.48 +V3*0.08+V4*0.12 三、镜像 围绕图像中心点,像素进行左右置换或上下置换。也称水平翻转,垂直翻转。 图像大小不变,处理后的数据写入原图像区域。 水平翻转函数: void FlipH() 《数字图像处理》几何变换 3 { int i,j,k1,k2; int halfW = Width/2; BYTE buf[3]; for(i=0;i 1. 对采样法缩小(放大)函数进行优化,写出优化后的函数。 2. 写出垂直翻转函数:void FlipV() 三、旋转 1. 问题 将图像绕中心点旋转一定角度。 将图像中的每个像素点变换到新的位置。 旋转后图像所占的正矩形区域将扩大。 k1 = i*WidthBytes; k2 = k1 + (Width-1)*3; for(j=0;j memcpy(ImageData+k1, ImageData+k2, 3); memcpy(ImageData+k2, buf, 3); k1+=3; k2-=3; } 2. 旋转计算公式 以逆时针旋转为正。 某点的坐标为(x', y'),绕原点旋转角,求旋转后的坐标(x, y)。 设(x', y')至原点的距离为r,与原点的连线与x轴的夹角为,则旋转后的夹角为。 《数字图像处理》几何变换 4 (x, y)(x’, y’)θα 则变换后的坐标为: xrcos()rcoscosrsinsinyrsin()rsincosrcossin 由于:xrcos,yrsin 可得: xxcosysinyycosxsin 采用该旋转公式计算四个角旋转后的位置可得到新图像的矩形区域。 3. 变换方式 正向映射,新图像中会形成空洞。 反向映射,不会存在空洞,但计算量增大,相当于在正向映射中用临近点填补空洞。 采用反向映射法, 相当于旋转角,公式为: 反向映射计算公式: xxcos()ysin()xcosysinyycos()xsin()ycosxsin 4. 程序 void Rotate(float d,BYTE *dImageData) { int dWidth,dHeight; CalcRotateSize(dWidth,dHeight,d); int dWidthBytes = (int)((dWidth*3+3)/4)*4; int dImageSize = dWidthBytes*dHeight; dImageData = (BYTE*)calloc(dImageSize,1); float cosV = cos(d), sinV = sin(d); float cx=Width/2.0, cy=Height/2.0; //原图像的中心点 float dcx=dWidth/2.0, dcy=dHeight/2.0; //新图像的中心点 BYTE blankCol[3]={0,0,0}; //空白处的颜色 int i,j,k,di,dj,dk; for(di=0;di } } dk=dWidthBytes*di; //新图中像素地址 for(dj=0;dj k = WidthBytes*i + 3*j; //原图中像素地址 memcpy(dImageData+dk, ImageData+k, 3); memcpy(dImageData+dk, blankCol, 3); else void CalcRotateSize(int &dWidth, int &dHeight, float d) { } 作业: 1. 对旋转函数进行优化,写出优化后的函数 2. float cosV=cos(d); float sinV=sin(d); int x[4]={0,Width-1,Width-1,0}; int y[4]={0,0,Height-1,Height-1}; int x1,y1,maxX,minX,maxY,minY; minX = minY = 0x7FFF; maxX = maxY = -0x7FFF; for(int i=0;i<4;i++) { } dWidth = maxX – minX + 1; dHeight = maxY – minY + 1; x1 = x[i]*cosV-y[i]*sinV+0.5; y1 = y[i]*cosV+x[i]*sinV+0.5; if( x1 《数字图像处理》几何变换 6 思考题: 1. 构造旋转后最大内接矩形的计算方法。内接矩形的宽高比及中心点与原图像相同。 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- 69lv.com 版权所有 湘ICP备2023021910号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务