前言
上一篇文章 ,我們講解了圖像金字塔,這篇文章我們來(lái)了解仿射變換。
?
仿射?!
任何仿射變換都可以轉(zhuǎn)換成,乘以一個(gè)矩陣(線性變化),再加上一個(gè)向量(平移變化)。
實(shí)際上仿射是兩幅圖片的變換關(guān)系。
例如我們可以通過(guò)仿射變換對(duì)圖片進(jìn)行:縮放、旋轉(zhuǎn)、平移等操作。
?
一個(gè)數(shù)學(xué)問(wèn)題
在解決仿射問(wèn)題前,我們來(lái)做一個(gè)數(shù)學(xué)題。
如圖,對(duì)于點(diǎn)(x1, y1),相對(duì)于原點(diǎn)旋轉(zhuǎn)一個(gè)角度a,那么這個(gè)點(diǎn)到哪里了呢?
我們將坐標(biāo)系變成極坐標(biāo)系,則點(diǎn)(x1, y1)就變成了(r, β ),而旋轉(zhuǎn)后變成(r, α ?+ β )。
轉(zhuǎn)回直角坐標(biāo)系,則旋轉(zhuǎn)后的點(diǎn)變成了(cos( α + β ) * r,?sin( α + β ) * r)。
然后利用公式:
cos(α+β)=cosαcosβ-sinαsinβ
sin(α+β)=sinαcosβ+cosαsinβ
以及原來(lái)點(diǎn)為(cosβ?* r, sinβ ?* r ),于是很容易得出新的點(diǎn)為(x1 * cos α - y1 * sin α,?x1 * sinaα + y1 * cosα )。
我們可以從中推導(dǎo)出旋轉(zhuǎn)變換公式:
那么平移就相對(duì)簡(jiǎn)單很多了,就相當(dāng)于加上一個(gè)向量(c, d)就行了。
?
獲得變換矩陣函數(shù)實(shí)現(xiàn)
通常我們使用矩陣來(lái)表示仿射變換。
其中A是旋轉(zhuǎn)縮放變換,B是平移變換。則結(jié)果T滿足:
?或者?
即:
var
getRotationArray2D =
function
(__angle, __x, __y){
var
sin = Math.sin(__angle) || 0
,
cos
= Math.cos(__angle) || 1
,
x
= __x || 0
,
y
= __y || 0
;
return
[cos, -sin, -
x,
sin, cos,
-
y
];
};
這樣我們就得到了一個(gè)仿射變換矩陣。
當(dāng)然這個(gè)實(shí)現(xiàn)本身是有一定問(wèn)題的,因?yàn)檫@個(gè)原點(diǎn)被固定在左上角了。
?
仿射變換實(shí)現(xiàn)
var
warpAffine =
function
(__src, __rotArray, __dst){
(__src
&& __rotArray) || error(arguments.callee, 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
Uint32Array(__src.buffer),
dData
=
new
Uint32Array(dst.buffer);
var
i, j, xs, ys, x, y, nowPix;
for
(j = 0, nowPix = 0; j < height; j++
){
xs
= __rotArray[1] * j + __rotArray[2
];
ys
= __rotArray[4] * j + __rotArray[5
];
for
(i = 0; i < width; i++, nowPix++, xs += __rotArray[0], ys += __rotArray[3
]){
if
(xs > 0 && ys > 0 && xs < width && ys <
height){
y
= ys | 0
;
x
= xs | 0
;
dData[nowPix]
= sData[y * width +
x];
}
else
{
dData[nowPix]
= 4278190080;
//
Black
}
}
}
}
else
{
error(arguments.callee, UNSPPORT_DATA_TYPE
/*
{line}
*/
);
}
return
dst;
};
這個(gè)函數(shù)先把矩陣數(shù)據(jù)變成32位形式,操作每個(gè)元素就等同于操作每一個(gè)像素。
然后遍歷所有元素,對(duì)對(duì)應(yīng)的點(diǎn)進(jìn)行賦值。
?
效果
?
?
系列目錄
?
參考資料
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

