zoukankan      html  css  js  c++  java
  • 《Computer Vision:Algorithms and Applications》学习笔记(一)——图像旋转算法与实现

          昨天和今天学习了《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 双线性插值算法图像旋转中应用".

  • 相关阅读:
    BP神经网络的数学原理及其算法实现
    机器学习必知的10大算法
    支持向量机通俗导论(理解SVM的三层境界)
    svm算法 最通俗易懂讲解
    read/write/fsync与fread/fwrite/fflush的关系和区别
    ubuntu16.04编译QT5.6所依赖的库
    Linux下的tar压缩解压缩命令详解
    Ubuntu16下编译linux内核,报"mkimage" command not found错的解决
    Git之(一)Git是什么[转]
    mac上完整卸载删除:android studio方案
  • 原文地址:https://www.cnblogs.com/mlv5/p/2336321.html
Copyright © 2011-2022 走看看