仿射變換(Affine Transformation)原理及應用(1)

仿射變換(Affine Transformation)原理及應用

1 什麼是仿射變換

  • 仿射變換(Affine Transformation)其實是另外兩種簡單變換的疊加:一個是線性變換,一個是平移變換

  • 仿射變換變化包括縮放(Scale、平移(transform)、旋轉(rotate)、反射(reflection,對圖形照鏡子)、錯切(shear mapping,感覺像是一個圖形的倒影),原來的直線仿射變換後還是直線,原來的平行線經過仿射變換之後還是平行線,這就是仿射

  • 仿射變換中集合中的一些性質保持不變:
    (1)凸性
    (2)共線性:若幾個點變換前在一條線上,則仿射變換後仍然在一條線上
    (3)平行性:若兩條線變換前平行,則變換後仍然平行
    (4)共線比例不變性:變換前一條線上兩條線段的比例,在變換後比例不變

2 仿射變換數學表達

一個集合 XX 的仿射變換爲:
f(x)=Ax+b,xXf(x)=Ax+b, \quad x\in X

仿射變換是二維平面中一種重要的變換,在圖像圖形領域有廣泛的應用,在二維圖像變換中,一般表達爲:
[xy1]=[R00R01TxR10R11Ty001][xy1]\begin{bmatrix} x' \\ y' \\ 1 \\ \end{bmatrix}= \begin{bmatrix} R_{00}&R_{01}&T_x \\ R_{10}&R_{11}&T_y \\ 0& 0& 1 \\ \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \\ \end{bmatrix}

可以視爲線性變換R和平移變換T的疊加

3 仿射變換理解

要熟練應用仿射變換,則需先理解仿射變換,說白了就是要弄清楚上面的R,T矩陣各個參數代表什麼含義,用圖像來表達:


在這裏插入圖片描述

3.1 平移變換

不難想象,就是將x,y平移指定值,則R矩陣爲單位矩陣,T矩陣爲指定值,如上圖中,第一行第二列圖
M=[10Tx01Ty001]M=\begin{bmatrix} 1&0&T_x \\ 0&1&T_y \\ 0& 0& 1 \\ \end{bmatrix}

3.2 反射變換

見圖最後一行,如相對x軸放射,則x不變,y變爲相反號
M=[100010001]M=\begin{bmatrix} 1&0&0 \\ 0&-1&0 \\ 0& 0& 1 \\ \end{bmatrix}

3.3 旋轉變換

關於旋轉矩陣,這裏詳細來看看,網上博客中,有朋友在疑惑旋轉矩陣中,sinθsin\theta的負號位置問題,下面我談談我個人想法,若有錯誤請大家指點。爲簡單起見,只從一個點的旋轉來看

(1) 左下角爲座標原點


在這裏插入圖片描述

  • 座標原點爲左下角
  • P(x,y)P(x,y)爲座標系中一個點,與x軸的夾角爲α\alpha,假設其到原點的距離爲1(方便計算)
  • P(x,y)P'(x',y')爲P點逆時針旋轉θ\theta角度的點
  • P(x,y)P''(x'',y'')爲P點順時針旋轉θ\theta角度的點

根據簡單三角關係,可知
{x=cosαy=sinα \begin{cases} x = cos\alpha\\ y = sin\alpha \end{cases}
逆時針時:
{x=cos(α+θ)=cosαcosθsinαsinθ=xcosθysinθy=sin(α+θ)=sinαcosθ+cosαsinθ=ycosθ+xsinθ \begin{cases} x' = cos(\alpha + \theta) = cos\alpha * cos\theta - sin\alpha*sin\theta = x* cos\theta - y*sin\theta \\ y' = sin(\alpha + \theta) = sin\alpha * cos\theta + cos\alpha*sin\theta = y* cos\theta + x*sin\theta \end{cases}
則,逆時針旋轉矩陣RR'爲:
R=[cosθsinθsinθcosθ] R'= \begin{bmatrix} cos\theta&-sin\theta\\ sin\theta&cos\theta\\ \end{bmatrix}

順時針時:
{x=cos(αθ)=cosαcosθ+sinαsinθ=xcosθ+ysinθy=sin(αθ)=sinαcosθcosαsinθ=ycosθxsinθ \begin{cases} x'' = cos(\alpha - \theta) = cos\alpha * cos\theta + sin\alpha*sin\theta = x* cos\theta + y*sin\theta \\ y'' = sin(\alpha - \theta) = sin\alpha * cos\theta - cos\alpha*sin\theta = y* cos\theta - x*sin\theta \end{cases}
則,順時針旋轉矩陣RR''爲:
R=[cosθsinθsinθcosθ] R''= \begin{bmatrix} cos\theta&sin\theta\\ -sin\theta&cos\theta\\ \end{bmatrix}

從上可以看出,這個負號位置問題,個人認爲與旋轉方向相關

(2)左上角爲座標原點


在這裏插入圖片描述

  • 座標原點爲左上角
  • P(x,y)P(x,y)爲座標系中一個點,與x軸的夾角爲α\alpha,假設其到原點的距離爲1(方便計算)
  • P(x,y)P'(x',y')爲P點逆時針旋轉θ\theta角度的點
  • P(x,y)P''(x'',y'')爲P點順時針旋轉θ\theta角度的點

根據簡單三角關係,可知
{x=cosαy=sinα \begin{cases} x = cos\alpha\\ y = sin\alpha \end{cases}
逆時針時:
{x=cos(αθ)=cosαcosθ+sinαsinθ=xcosθ+ysinθy=sin(αθ)=sinαcosθcosαsinθ=ycosθxsinθ \begin{cases} x' = cos(\alpha - \theta) = cos\alpha * cos\theta + sin\alpha*sin\theta = x* cos\theta + y*sin\theta \\ y' = sin(\alpha - \theta) = sin\alpha * cos\theta - cos\alpha*sin\theta = y* cos\theta - x*sin\theta \end{cases}
則,逆時針旋轉矩陣RR'爲:
R=[cosθsinθsinθcosθ] R'= \begin{bmatrix} cos\theta&sin\theta\\ -sin\theta&cos\theta\\ \end{bmatrix}

順時針時:
{x=cos(α+θ)=cosαcosθsinαsinθ=xcosθysinθy=sin(α+θ)=sinαcosθ+cosαsinθ=ycosθ+xsinθ \begin{cases} x'' = cos(\alpha + \theta) = cos\alpha * cos\theta - sin\alpha*sin\theta = x* cos\theta - y*sin\theta \\ y'' = sin(\alpha + \theta) = sin\alpha * cos\theta + cos\alpha*sin\theta = y* cos\theta + x*sin\theta \end{cases}
則,順時針旋轉矩陣RR''爲:
R=[cosθsinθsinθcosθ] R''= \begin{bmatrix} cos\theta&-sin\theta\\ sin\theta&cos\theta\\ \end{bmatrix}

從上可以看出,這個負號位置問題,不但與旋轉方向有關,還與原點有關

(3)總結

  • 旋轉矩陣R中,sinθsin\theta的負號位置與旋轉方向和原點相關
  • 當記逆時針爲正,左上角爲原點時(opencv默認),旋轉矩陣爲:
    R=[cosθsinθsinθcosθ] R= \begin{bmatrix} cos\theta&sin\theta\\ -sin\theta&cos\theta\\ \end{bmatrix}

3.4 opencv中的仿射矩陣

getRotationMatrix2D函數

CV_EXPORTS_W Mat getRotationMatrix2D( Point2f center, double angle, double scale )

該函數是來計算仿射矩陣:

[αβ(1α)center.xβcenter.yβαβcenter.x+(1α)center.y]\begin{bmatrix} \alpha & \beta & (1- \alpha ) \cdot \texttt{center.x} - \beta \cdot \texttt{center.y} \\ - \beta & \alpha & \beta \cdot \texttt{center.x} + (1- \alpha ) \cdot \texttt{center.y} \end{bmatrix}

其中

α=scalecosangle,β=scalesinangle\begin{array}{l} \alpha = \texttt{scale} \cdot \cos \texttt{angle} , \\ \beta = \texttt{scale} \cdot \sin \texttt{angle} \end{array}

  • center:源圖旋轉中心

  • angle: 旋轉角度,用角度表示;逆時針旋轉爲正(座標原點設爲左上角)

     Rotation angle in degrees. 
     Positive values mean counter-clockwise rotation (thecoordinate origin is assumed to be the top-left corner).
    
  • scale:各向同比縮放因子

  • 源碼

     	cv::Mat cv::getRotationMatrix2D( Point2f center, double angle, double scale )
     	{
     	    CV_INSTRUMENT_REGION();
     	
     	    angle *= CV_PI/180;
     	    double alpha = std::cos(angle)*scale;
     	    double beta = std::sin(angle)*scale;
     	
     	    Mat M(2, 3, CV_64F);
     	    double* m = M.ptr<double>();
     	
     	    m[0] = alpha;
     	    m[1] = beta;
     	    m[2] = (1-alpha)*center.x - beta*center.y;
     	    m[3] = -beta;
     	    m[4] = alpha;
     	    m[5] = beta*center.x + (1-alpha)*center.y;
     	
     	    return M;
     	}
    
  • 矩陣由來:首先將軸心(x,y)移到原點,然後做旋轉縮放變換,最後再將圖像的左上角轉換爲原點
    M=[10x01y001][cosθsinθ0sinθcosθ0001][s000s0001][10x01y001] M= \begin{bmatrix} 1 &amp; 0 &amp;x \\ 0&amp;1 &amp; y\\ 0&amp; 0 &amp;1 \end{bmatrix} \begin{bmatrix} cos\theta &amp;sin\theta &amp;0 \\ -sin\theta &amp; cos\theta &amp; 0\\ 0 &amp; 0 &amp; 1 \end{bmatrix} \begin{bmatrix} s &amp; 0 &amp; 0\\ 0&amp;s &amp; 0\\ 0 &amp;0 &amp; 1 \end{bmatrix} \begin{bmatrix} 1 &amp; 0 &amp; -x\\ 0 &amp; 1 &amp;-y \\ 0&amp; 0 &amp; 1 \end{bmatrix}

4 參考文獻

[1]仿射變換詳解 warpAffine :https://www.cnblogs.com/dupuleng/articles/4055020.html
[2]仿射變換(Affine transformation): https://blog.csdn.net/robert_chen1988/article/details/80498805
[3]opencv學習(三十五)之仿射變換warpAffine: https://blog.csdn.net/keith_bb/article/details/56331356

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章