《Computer Vision:Algorithms and Applications》学习笔记(一)——图像旋转算法与实现

∥☆過路亽.° 提交于 2020-03-22 21:20:53

      昨天和今天学习了《Computer Vision:Algorithms and Applications》中第二章“Image formation”前半部分,主要是如何表示2D、3D图像中的点、线、面等,以及如何用公式推导出2D图形的几何变换,如位移、旋转、放缩、仿射变换、投射等,如下图所示:

一、图像旋转方法简介   

   其中的图像旋转是一种常用的数字图像处理技术。由于旋转后图像像素点坐标不再是整数,所以旋转后必须对新的像素点灰度值进行插值运算。目前常用的方法有最近邻插值法、线性插值法和样条插值法。文献介绍,最近邻法速度快,方法简单,但生成图像效果较差;样条插值法计算精度高,效果好,但计算复杂,速度较慢;线性插值法(E.g. 双线性插值法)效果较好,运行时间较短。另外,实现赋值的方法分为正向映射法和反向映射法:正向映射法是指,从原始图像坐标出发,计算出在旋转图像上坐标,然后将原始图像该坐标的灰度值赋给对应旋转图像该坐标点;反向映射法则反之。

     本文将分别采用基于最近邻取值的正向映射法、基于最近邻取值的反向映射法、基于双线性插值的反向映射法实现图像旋转,并对比三种方法的效果。       

 

二、本文方法

1. 基于最近邻取值的正向映射法

   这种方法最简单,也最直观,先考虑图像旋转原理:

以顺时针旋转为例来堆到旋转变换公式。如下图所示。

 

 

旋转前:

x0=rcosby0=rsinb

旋转a角度后:

x1=rcos(b-a)=rcosbcosa+rsinbsina=x0cosa+y0sina

y1=rsin(b-a)=rsinbcosa-rcosbsina=-x0sina+y0cosa

正向映射即根据原图的坐标推导出旋转图像对应点坐标,然后直接将原图坐标灰度值赋给x1,y1

 

2.基于最近邻取值的反向映射法

旋转前:

x1=rcoscy1=rsinc

旋转a角度后:

x0=rcos(c+a)=rcosccosa-rsincsina=x1cosa-y1sina

y0=rsin(c+a)=rsinccosa+rcoscsina=-x1sina+y1cosa

反向映射即已知旋转后图像坐标,通过公式推导出原始图像上对应坐标,将该坐标对应灰度值赋给旋转后坐标。因为计算得到的y0, x0非整数,最近邻方法即将与(Xo,Yo)距离最近的像素的灰度值作为(Xo,Yo)的灰度值赋给(X1,Y1)点。

 

3.基于双线性插值的反向映射法

在计算(Xo,Yo)的灰度值时,采用如下方法计算:

 

三、实验对比

     三种实验结果的对比图如下:

可见,双线性插值法获得的旋转图像更平滑,接近真实图像。

 

三种方法的matlab代码如下

  1 Image=imread('E:\1.jpg');  2   3 %X,Y为其行列数  4 angle=30;  5 %角度任意的一个数 表示30度  6 pai=3.1415929657;  7 Angle=pai*angle/180;  8 %转换一下角度的表示方法。  9 [Y,X,Z]=size(Image); 10 %原图显示 11 subplot(2,2,1); 12 imshow(Image); 13 title('原图像'); 14  15 %  16 %计算四个角点的新坐标,确定旋转后的显示区域 17 LeftBottom(1,1)=(Y-1)*sin(Angle); 18 LeftBottom(1,2)=(Y-1)*cos(Angle); 19  20 LeftTop(1,1)=0; 21 LeftTop(1,2)=0; 22  23 RightBottom(1,1)=(X-1)*cos(Angle)+(Y-1)*sin(Angle); 24 RightBottom(1,2)=-(X-1)*sin(Angle)+(Y-1)*cos(Angle); 25  26 RightTop(1,1)=(X-1)*cos(Angle); 27 RightTop(1,2)=-(X-1)*sin(Angle); 28  29 %计算显示区域的行列数 30 Xnew=max([LeftTop(1,1),LeftBottom(1,1),RightTop(1,1),RightBottom(1,1)])-min([LeftTop(1,1),LeftBottom(1,1),RightTop(1,1),RightBottom(1,1)]); 31 Ynew=max([LeftTop(1,2),LeftBottom(1,2),RightTop(1,2),RightBottom(1,2)])-min([LeftTop(1,2),LeftBottom(1,2),RightTop(1,2),RightBottom(1,2)]); 32  33 % 分配新显示区域矩阵 34 ImageNewForward=zeros(round(Ynew),round(Xnew),3)+255; 35 ImageNewIntersection=zeros(round(Ynew),round(Xnew),3)+255; 36 ImageNew1nn=zeros(round(Ynew),round(Xnew),3)+255; 37  38 %计算原图像各像素的新坐标:正向映射法 39 for indexX=0:(X-1) 40     for indexY=0:(Y-1) 41         Yn=1+round(-indexX*sin(Angle)+indexY*cos(Angle))+round(abs(min([LeftTop(1,2),LeftBottom(1,2),RightTop(1,2),RightBottom(1,2)]))); 42         Xn=round(indexX*cos(Angle)+indexY*sin(Angle))+round(abs(min([LeftTop(1,1),LeftBottom(1,1),RightTop(1,1),RightBottom(1,1)])))+1; 43         ImageNewForward(Yn,Xn,1)=Image(indexY+1,indexX+1,1); 44         ImageNewForward(Yn,Xn,2)=Image(indexY+1,indexX+1,2); 45         ImageNewForward(Yn,Xn,3)=Image(indexY+1,indexX+1,3); 46     end  47 end 48  49 %%反向映射法 50 for indexY=1:round(Ynew) 51     for indexX=1:round(Xnew) 52         Y1=indexY-round(abs(min([LeftTop(1,2),LeftBottom(1,2),RightTop(1,2),RightBottom(1,2)]))); 53         X1=indexX-round(abs(min([LeftTop(1,1),LeftBottom(1,1),RightTop(1,1),RightBottom(1,1)]))); 54         Yoo=X1*sin(Angle)+Y1*cos(Angle); 55         Xoo=X1*cos(Angle)-Y1*sin(Angle); 56         Yo=round(Yoo); 57         Xo=round(Xoo); 58         if 1<Xo&&Xo<X&&1<Yo&&Yo<Y 59             %最近邻法 60             ImageNew1nn(indexY,indexX,1)=Image(Yo,Xo,1); 61             ImageNew1nn(indexY,indexX,2)=Image(Yo,Xo,2); 62             ImageNew1nn(indexY,indexX,3)=Image(Yo,Xo,3); 63              64             %双线性插值法 65             left=floor(Xoo); 66             right=ceil(Xoo); 67             up=floor(Yoo); 68             down=ceil(Yoo); 69              70             upmid1=(1-Xoo+left)*Image(up,left,1)+(Xoo-left)*Image(up,right,1); 71             downmid1=(1-Xoo+left)*Image(down,left,1)+(Xoo-left)*Image(down,right,1); 72             upmid2=(1-Xoo+left)*Image(up,left,2)+(Xoo-left)*Image(up,right,2); 73             downmid2=(1-Xoo+left)*Image(down,left,2)+(Xoo-left)*Image(down,right,2); 74             upmid3=(1-Xoo+left)*Image(up,left,3)+(Xoo-left)*Image(up,right,3); 75             downmid3=(1-Xoo+left)*Image(down,left,3)+(Xoo-left)*Image(down,right,3); 76             central1=(1-Yoo+up)*upmid1+(Yoo-up)*downmid1; 77             central2=(1-Yoo+up)*upmid2+(Yoo-up)*downmid2; 78             central3=(1-Yoo+up)*upmid3+(Yoo-up)*downmid3; 79              80             ImageNew(indexY,indexX,1)=central1; 81             ImageNew(indexY,indexX,2)=central2; 82             ImageNew(indexY,indexX,3)=central3;     83              84         else 85              ImageNew(indexY,indexX,:)=255; 86         end 87     end 88 end 89  90 %显示 91 subplot(2,2,2); 92 ImageNewForward=uint8(ImageNewForward); 93 imshow(ImageNewForward); 94 promp=['旋转角度为:' int2str(angle) '度图像 正向映射法']; 95 title(promp); 96  97 subplot(2,2,3); 98 ImageNew1nn=uint8(ImageNew1nn); 99 imshow(ImageNew1nn);100 promp=['旋转角度为:' int2str(angle) '度图像 最近邻插值法'];101 title(promp);102 103 subplot(2,2,4);104 ImageNew=uint8(ImageNew);105 imshow(ImageNew);106 promp=['旋转角度为:' int2str(angle) '度图像 双线性插值法'];107 title(promp);



参考文献:

1. 《Computer Vision:Algorithms and Applications》,pp30-40

2. 曹佃国, 陈浩杰,李鹏, "基于 Matlab 双线性插值算法图像旋转中应用".

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!