仿射變換(Affine Transformation)原理及應用
1 什麼是仿射變換
-
仿射變換(Affine Transformation)其實是另外兩種簡單變換的疊加:一個是線性變換,一個是平移變換
-
仿射變換變化包括縮放(Scale、平移(transform)、旋轉(rotate)、反射(reflection,對圖形照鏡子)、錯切(shear mapping,感覺像是一個圖形的倒影),原來的直線仿射變換後還是直線,原來的平行線經過仿射變換之後還是平行線,這就是仿射
-
仿射變換中集合中的一些性質保持不變:
(1)凸性
(2)共線性:若幾個點變換前在一條線上,則仿射變換後仍然在一條線上
(3)平行性:若兩條線變換前平行,則變換後仍然平行
(4)共線比例不變性:變換前一條線上兩條線段的比例,在變換後比例不變
2 仿射變換數學表達
一個集合 XX 的仿射變換爲:
f(x)=Ax+b,x∈X
仿射變換是二維平面中一種重要的變換,在圖像圖形領域有廣泛的應用,在二維圖像變換中,一般表達爲:
⎣⎡x′y′1⎦⎤=⎣⎡R00R100R01R110TxTy1⎦⎤⎣⎡xy1⎦⎤
可以視爲線性變換R和平移變換T的疊加
3 仿射變換理解
要熟練應用仿射變換,則需先理解仿射變換,說白了就是要弄清楚上面的R,T矩陣各個參數代表什麼含義,用圖像來表達:
3.1 平移變換
不難想象,就是將x,y平移指定值,則R矩陣爲單位矩陣,T矩陣爲指定值,如上圖中,第一行第二列圖
M=⎣⎡100010TxTy1⎦⎤
3.2 反射變換
見圖最後一行,如相對x軸放射,則x不變,y變爲相反號
M=⎣⎡1000−10001⎦⎤
3.3 旋轉變換
關於旋轉矩陣,這裏詳細來看看,網上博客中,有朋友在疑惑旋轉矩陣中,sinθ的負號位置問題,下面我談談我個人想法,若有錯誤請大家指點。爲簡單起見,只從一個點的旋轉來看
(1) 左下角爲座標原點
- 座標原點爲左下角
- 點P(x,y)爲座標系中一個點,與x軸的夾角爲α,假設其到原點的距離爲1(方便計算)
- 點P′(x′,y′)爲P點逆時針旋轉θ角度的點
- 點P′′(x′′,y′′)爲P點順時針旋轉θ角度的點
根據簡單三角關係,可知
{x=cosαy=sinα
逆時針時:
{x′=cos(α+θ)=cosα∗cosθ−sinα∗sinθ=x∗cosθ−y∗sinθy′=sin(α+θ)=sinα∗cosθ+cosα∗sinθ=y∗cosθ+x∗sinθ
則,逆時針旋轉矩陣R′爲:
R′=[cosθsinθ−sinθcosθ]
順時針時:
{x′′=cos(α−θ)=cosα∗cosθ+sinα∗sinθ=x∗cosθ+y∗sinθy′′=sin(α−θ)=sinα∗cosθ−cosα∗sinθ=y∗cosθ−x∗sinθ
則,順時針旋轉矩陣R′′爲:
R′′=[cosθ−sinθsinθcosθ]
從上可以看出,這個負號位置問題,個人認爲與旋轉方向相關
(2)左上角爲座標原點
- 座標原點爲左上角
- 點P(x,y)爲座標系中一個點,與x軸的夾角爲α,假設其到原點的距離爲1(方便計算)
- 點P′(x′,y′)爲P點逆時針旋轉θ角度的點
- 點P′′(x′′,y′′)爲P點順時針旋轉θ角度的點
根據簡單三角關係,可知
{x=cosαy=sinα
逆時針時:
{x′=cos(α−θ)=cosα∗cosθ+sinα∗sinθ=x∗cosθ+y∗sinθy′=sin(α−θ)=sinα∗cosθ−cosα∗sinθ=y∗cosθ−x∗sinθ
則,逆時針旋轉矩陣R′爲:
R′=[cosθ−sinθsinθcosθ]
順時針時:
{x′′=cos(α+θ)=cosα∗cosθ−sinα∗sinθ=x∗cosθ−y∗sinθy′′=sin(α+θ)=sinα∗cosθ+cosα∗sinθ=y∗cosθ+x∗sinθ
則,順時針旋轉矩陣R′′爲:
R′′=[cosθsinθ−sinθcosθ]
從上可以看出,這個負號位置問題,不但與旋轉方向有關,還與原點有關
(3)總結
- 旋轉矩陣R中,sinθ的負號位置與旋轉方向和原點相關
- 當記逆時針爲正,左上角爲原點時(opencv默認),旋轉矩陣爲:
R=[cosθ−sinθsinθcosθ]
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]
其中
α=scale⋅cosangle,β=scale⋅sinangle
-
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=⎣⎡100010xy1⎦⎤⎣⎡cosθ−sinθ0sinθcosθ0001⎦⎤⎣⎡s000s0001⎦⎤⎣⎡100010−x−y1⎦⎤
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