什么是仿射變換?
仿射變換(Affine Transformation)是空間直角坐標(biāo)系的變換,從一個(gè)二維坐標(biāo)變換到另一個(gè)二維坐標(biāo),仿射變換是一個(gè)線性變換,他保持了圖像的“平行性”和“平直性”,即圖像中原來的直線和平行線,變換后仍然保持原來的直線和平行線,仿射變換比較常用的特殊變換有平移(Translation)、縮放(Scale)、翻轉(zhuǎn)(Flip)、旋轉(zhuǎn)(Rotation)和剪切(Shear)。
線性變換和仿射變換的差別
線性變換 | 仿射變換 |
---|---|
變換前是直線的,變換后依然是直線直線比例保持不變變換前是原點(diǎn)的,變換后依然是原點(diǎn) | 變換前是直線的,變換后依然是直線直線比例保持不變 |
線性變換和仿射變換的差別在原點(diǎn)是否改變
空間變換的兩個(gè)主要類別
仿射變換
仿射變換:平移、旋轉(zhuǎn)、放縮、剪切、反射
仿射變換的公式表達(dá)
( X 2 Y 2 1 ) = [ A 11 A 12 B 11 A 21 A 22 B 12 0 0 1 ] × ( X 1 Y 1 1 ) \left(\begin{array}{c} X_{2} \\ Y_{2} \\ 1 \end{array}\right)=\left[\begin{array}{ccc} A_{11} & A_{12} & B_{11} \\ A_{21} & A_{22} & B_{12} \\ 0 & 0 & 1 \end{array}\right] \times\left(\begin{array}{c} X_{1} \\ Y_{1} \\ 1 \end{array}\right) ? ??X2?Y2?1?? ??=? ??A11?A21?0?A12?A22?0?B11?B12?1?? ??×? ??X1?Y1?1?? ??
通過上述的矩陣轉(zhuǎn)換可以將圖像進(jìn)行平移、縮放、旋轉(zhuǎn)和剪切,如下圖所示
仿射變換在ML機(jī)器學(xué)習(xí)領(lǐng)域的應(yīng)用
仿射變換的思想在機(jī)器學(xué)習(xí)“圖像處理”領(lǐng)域?qū)?yīng)單應(yīng)性矩陣
在三軸坐標(biāo)中 X Y Z , Z = 1 XYZ,Z=1 XYZ,Z=1這個(gè)有點(diǎn)類似于三維的齊次坐標(biāo)。單應(yīng)性矩陣主要用來解決兩個(gè)問題,
- 表述真實(shí)世界(Unity中的主世界相機(jī)視角)中一個(gè)平面與對應(yīng)它圖像的透視變換
- 從通過透視變換實(shí)現(xiàn)圖像從一種視圖變換到另外一種視圖
上圖的中零點(diǎn)分別表示兩個(gè)平面中任意兩個(gè)點(diǎn),a1、a2與b1、b2是這兩點(diǎn)對應(yīng)的兩個(gè)方向上的線性向量。對于這兩個(gè)平面之間的關(guān)系,我們可以通過這些點(diǎn)從而一步確定兩個(gè)平面直接的關(guān)系,而兩個(gè)平面之間的關(guān)系用單應(yīng)性矩陣來描述如下:
p
h
→
=
H
q
?
h
?
\overrightarrow{p^{h}}=H \vec{q}^{\vec{h}}
ph?=Hq?h
其中,
?
p
h
→
,
q
?
h
?
- \overrightarrow{p^{h}},\vec{q}^{\vec{h}}
?ph?,q?h表示三維的齊次坐標(biāo)向量
這種關(guān)系被稱為平面單應(yīng)性。這個(gè)當(dāng)中有一些數(shù)學(xué)知識(shí)推導(dǎo),這里不做證明,只是明白這個(gè)概念怎么來的。
- 此外兩個(gè)計(jì)算機(jī)圖形學(xué)的應(yīng)用場景分布是紋理渲染與計(jì)算平面陰影。
- 用來實(shí)現(xiàn)圖像拼接時(shí)候解決對齊問題
投影變換
(
x
1
t
x
2
t
x
3
t
)
=
[
h
11
h
12
h
13
h
21
h
22
h
23
h
31
h
32
h
33
]
(
x
1
x
2
x
3
)
\left(\begin{array}{l} x_{1}^{t} \\ x_{2}^{t} \\ x_{3}^{t} \end{array}\right)=\left[\begin{array}{lll} h_{11} & h_{12} & h_{13} \\ h_{21} & h_{22} & h_{23} \\ h_{31} & h_{32} & h_{33} \end{array}\right]\left(\begin{array}{l} x_{1} \\ x_{2} \\ x_{3} \end{array}\right)
?
??x1t?x2t?x3t???
??=?
??h11?h21?h31??h12?h22?h32??h13?h23?h33???
???
??x1?x2?x3???
??
投影和仿射變換之間的區(qū)別
投影變換 | 仿射變換 |
---|---|
變換前是直線的,變換后依然是直線直線比例改變變換前平行的兩條線,變換后不一定平行 | 變換前是直線的,變換后依然是直線直線比例改變變換前平行的兩條線,變換后不一定平行 |
這些仿射變換和投影變換之間的唯一區(qū)別在于變換矩陣的最后一行。對于仿射變換,該行的前兩個(gè)元素為零。這導(dǎo)致操作屬性存在以下差異:
-
投影變換不保留平行度、長度和角度。
-
仿射變換與投影變換不同,保留了并行性。
射影變換可以表示為任意四邊形(即四點(diǎn)系統(tǒng))到另一個(gè)四邊形的變換。仿射變換是三角形的變換。下圖說明了這一點(diǎn):
直觀的例子:
仿射變換:
仿射變換C#代碼實(shí)現(xiàn)
在Graphics Mill中應(yīng)用仿射變換,請執(zhí)行以下步驟:
-
指定源和目標(biāo)三角形。
-
使用Matrix.CreateFromAffinePoints(PointF[], PointF[])創(chuàng)建仿射變換矩陣。將先前指定的點(diǎn)作為方法參數(shù)傳遞。
-
使用MatrixTransform.#ctor構(gòu)造函數(shù)創(chuàng)建轉(zhuǎn)換。這里之前創(chuàng)建的矩陣是構(gòu)造函數(shù)的參數(shù)。
-
通過調(diào)用MatrixTransform.Apply方法應(yīng)用轉(zhuǎn)換。
using (var bitmap = new Bitmap(@"Images\in.jpg"))
{
System.Drawing.PointF[] source = {
new System.Drawing.PointF(0f, 0f),
new System.Drawing.PointF(0f, 80f),
new System.Drawing.PointF(80f, 0f)
};
System.Drawing.PointF[] target = {
new System.Drawing.PointF(20, 0f),
new System.Drawing.PointF(0f, 80f),
new System.Drawing.PointF(80f, 0f)
};
using (var matrix = Matrix.CreateFromAffinePoints(source, target))
{
using (var transform = new MatrixTransform(matrix))
{
using (var result = transform.Apply(bitmap))
{
result.Save(@"Images\Output\out.jpg");
}
}
}
}
投影變換:
投影變換C#代碼實(shí)現(xiàn)
在Graphics Mill中應(yīng)用投影變換,請執(zhí)行以下步驟:
- 指定源四邊形和目標(biāo)四邊形。
- 使用Matrix.CreateFromProjectivePoints(PointF[], PointF[])創(chuàng)建投影變換矩陣。將先前指定的點(diǎn)作為方法參數(shù)傳遞。
- 使用MatrixTransform.#ctor構(gòu)造函數(shù)創(chuàng)建轉(zhuǎn)換。這里之前創(chuàng)建的矩陣是構(gòu)造函數(shù)的參數(shù)。
- 通過調(diào)用MatrixTransform.Apply方法應(yīng)用轉(zhuǎn)換。
using (var bitmap = new Bitmap(@"Images\in.jpg"))
{
System.Drawing.PointF[] source = {
new System.Drawing.PointF(0f, 0f),
new System.Drawing.PointF(0f, bitmap.Height),
new System.Drawing.PointF(bitmap.Width, bitmap.Height),
new System.Drawing.PointF(bitmap.Width, 0f)
};
System.Drawing.PointF[] target = {
new System.Drawing.PointF(0f, 0f),
new System.Drawing.PointF(0f, bitmap.Height),
new System.Drawing.PointF(bitmap.Width * 0.75f, bitmap.Height - 50f),
new System.Drawing.PointF(bitmap.Width * 0.75f, 80f)
};
using (var matrix = Matrix.CreateFromProjectivePoints(source, target))
{
using (var transform = new MatrixTransform(matrix))
{
using (var result = transform.Apply(bitmap))
{
result.Save(@"Images\Output\out.jpg");
}
}
}
}
仿射變換在機(jī)器學(xué)習(xí)中的應(yīng)用
在用CNN模型處理MINST手寫數(shù)據(jù)集的識(shí)別中,引入了仿射變換的方法提升了識(shí)別準(zhǔn)確性
論文:https://arxiv.org/abs/1506.02025
參考資料:文章來源:http://www.zghlxwxcb.cn/news/detail-465089.html
仿射和投影變換 - Graphics Mill
Review: STN — Spatial Transformer Network (Image Classification)
如何通俗地講解「仿射變換」這個(gè)概念? - 馬同學(xué)的回答 - 知乎文章來源地址http://www.zghlxwxcb.cn/news/detail-465089.html
到了這里,關(guān)于【CV & Unity】仿射變換原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!