javascript圖像處理—仿射變換深度理解
上一篇文章,我們講解了圖像金字塔,這篇文章我們來了解仿射變換。
仿射?
任何仿射變換都可以轉(zhuǎn)換成,乘以一個(gè)矩陣(線性變化),再加上一個(gè)向量(平移變化)。
實(shí)際上仿射是兩幅圖片的變換關(guān)系。
例如我們可以通過仿射變換對(duì)圖片進(jìn)行:縮放、旋轉(zhuǎn)、平移等操作。
一個(gè)數(shù)學(xué)問題
在解決仿射問題前,我們來做一個(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β
以及原來點(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)
通常我們使用
矩陣來表示仿射變換。

其中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)本身是有一定問題的,因?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)行賦值。
效果

- JavaScript圖像放大鏡效果實(shí)現(xiàn)方法詳解
- JavaScript如何使用插值實(shí)現(xiàn)圖像漸變
- JavaScript實(shí)現(xiàn)圖像模糊化的方法實(shí)例
- Javascript基礎(chǔ)_嵌入圖像的簡(jiǎn)單實(shí)現(xiàn)
- JavaScript圖像延遲加載庫Echo.js
- javascript實(shí)現(xiàn)圖像循環(huán)明暗變化的方法
- JS預(yù)覽圖像將本地圖片顯示到瀏覽器上
- Javascript圖像處理—圖像形態(tài)學(xué)(膨脹與腐蝕)
- Javascript圖像處理—為矩陣添加常用方法
- 10大Js圖像處理庫
相關(guān)文章
BootStrap select2 動(dòng)態(tài)改變值的方法
這篇文章主要介紹了BootStrap select2 動(dòng)態(tài)改變值的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-02-02
JS面向?qū)ο缶幊虒?shí)現(xiàn)的Tab選項(xiàng)卡案例詳解
這篇文章主要介紹了JS面向?qū)ο缶幊虒?shí)現(xiàn)的Tab選項(xiàng)卡,結(jié)合具體案例形式詳細(xì)分析了JS基于面向?qū)ο蟪绦蛟O(shè)計(jì)實(shí)現(xiàn)Tab選項(xiàng)卡的相關(guān)操作技巧,需要的朋友可以參考下2020-03-03
js字符限制(字符截取) 一個(gè)中文漢字算兩個(gè)字符
有時(shí)候我們需要限制用戶的輸入或者需要截取一定長(zhǎng)度的字符串都需要用到這樣的功能代碼,這里腳本之家小編就為大家分享一下2017-09-09
JS實(shí)現(xiàn)倒計(jì)時(shí)和文字滾動(dòng)的效果實(shí)例
這篇文章主要介紹了JS實(shí)現(xiàn)倒計(jì)時(shí)和文字滾動(dòng)的效果,以實(shí)例的形式分析了倒計(jì)時(shí)與文字滾動(dòng)效果的具體實(shí)現(xiàn)方法,并附有js時(shí)間變量的說明,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-10-10
springMvc 前端用json的方式向后臺(tái)傳遞對(duì)象數(shù)組方法
今天小編就為大家分享一篇springMvc 前端用json的方式向后臺(tái)傳遞對(duì)象數(shù)組方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-08-08
一個(gè)簡(jiǎn)單但常用的javascript表格樣式_鼠標(biāo)劃過行變色 簡(jiǎn)潔實(shí)現(xiàn)
經(jīng)常性的會(huì)需要使用表格顯示一些東西,當(dāng)表格比較大的時(shí)候一眼望去腦袋可能會(huì)有些暈,經(jīng)常性的因?yàn)闆]看準(zhǔn)行而出現(xiàn)誤操作,一般解決辦法是交替行變行或者鼠標(biāo)劃過行變色2008-09-09
JavaScript遞歸操作樹形結(jié)構(gòu)代碼示例
前端樹形結(jié)構(gòu)一般用于網(wǎng)頁的地理位置輸入框,地理位置級(jí)聯(lián)選擇,人員的部門選擇等,這篇文章主要給大家介紹了關(guān)于JavaScript遞歸操作樹形結(jié)構(gòu)的相關(guān)資料,需要的朋友可以參考下2024-01-01

