前言在上一篇文章中,我们解释了图像金字塔。在这篇文章中,我们开始理解仿射变换。仿射?任何仿射变换都可以变换成矩阵(线性变化)和向量(平移变化)。其实仿射就是两张图片之间的变换关系。例如,我们可以通过仿射变换进行缩放、旋转、平移等操作。一道数学题在解决仿射问题之前,我们先做一道数学题。
如图所示,点(x1,y1)相对原点旋转了一个角度a,那么这个点在哪里呢?当我们把坐标系改成极坐标时,点(x1,y1)变成(r,),旋转后变成(r, )。回到直角坐标系,旋转后的点变成(cos( ) * r,sin( ) * r)。然后利用公式:cos()=coscos-sinsinsin()=sincoscossin和原点(cos* r,sin* r),很容易得到新点(x1 * cos -y1 * sin ,x1 * Sina y1 * cos )。我们可以从中推导出旋转变换的公式:。
那么翻译就简单多了,相当于加了一个向量(c,d)。我们通常用来实现变换矩阵函数。
表示仿射变换的矩阵。
其中a是旋转缩放变换,b是平移变换。结果t满意:。
或者
即:。
复制的代码如下: VAR GetRotationArray 2D=Function(_ angle,_ _ x,_ _ y){ VAR SIN=math . SIN(_ angle)| | 0,COS=math . COS(_ angle)| | 1,X=_ _ x | | 0。返回[cos,-sin,-x,sin,cos,-y];};所以我们得到一个仿射变换矩阵。当然,这个实现本身也有一些问题,因为原点固定在左上角。仿射变换实现复制代码如下: var warp仿射=function(_ src,_ _ rotary,_ _ dst){(_ _ src _ _ rotary)| | error(自变量。被调用者,is _ undefined _ or _ null/* { line } */);if(_ src . type _ _ src . type==' CV_RGBA '){ var height=_ _ src . row,width=__src.col,dst=__dst || new Mat(height,width,CV _ RGBA),sData=new uint 32 array(_ src . buffer),dData=new uint 32 array(dst . buffer);var i,j,xs,ys,x,y,nowPixfor(j=0,now pix=0;j身高;j){ xs=_ _ rotArray[1]* j _ _ rotArray[2];ys=_ _ rotArray[4]* j _ _ rotArray[5];for(I=0;I宽度;I,nowPix,xs=__rotArray[0],ys=_ _ rotArray[3]){ if(xs 0 ys 0 xs width ys height){ y=ys | 0;x=xs | 0;dData[now pix]=sData[y * width x];} else { dData[now pix]=4278190080;//Black } } } } else { error(arguments . caller,UNSPORT _ DATA _ TYPE/* { line } */);}返回dst};该函数首先将矩阵数据转换为32位格式,操纵每个元素相当于操纵每个像素。然后遍历所有元素,并为相应的点赋值。效果