Javascript影像處理—為矩陣添加常用方法

來源:互聯網
上載者:User

前言
上一篇文章,我們定義了矩陣,這篇文章我們來給矩陣添加一些常用方法。

toString方法
toString方法通常用作將對象轉成字串描述,所以我們將這一方法定義為輸出矩陣元素。 複製代碼 代碼如下:Mat.prototype.toString = function(){
var tempData = this.data,
text = "Mat("+ this.type +") = {\n",
num = this.col * this.channel;
for(var i = 0; i < this.row; i++){
text += "["
for(var j = 0; j < num; j++){
text += (tempData[i * num + j] + ",");
}
text += "]\n";
}
text += "}";
return text;
};

這樣,我們就可以通過: 複製代碼 代碼如下:console.log(mat);

來輸出矩陣了。

clone方法
實際上,我們可以通過建構函式進行複製操作,不過依然提供一個方法來方便記憶、使用。 複製代碼 代碼如下:Mat.prototype.clone = function(){
return new Mat(this.row, this.col, this.data);
};

擷取指定元素
我們有兩種方法擷取矩陣元素。

數組方法
由於實際上Mat是以數組形式儲存資料的,而資料看起來是這樣的:
R00 G00 B00 A00 R01 G01 B01 A01 …… R0n G0n B0n A0n
R10 G10 B10 A10 R11 G11 B11 A11 …… R1n G1n B1n A1n
……
Rm0 Gm0 Bm0 Am0 Rm1 Gm1 Bm1 Am1 …… Rmn Gmn Bmn Amn
其中大寫R、G、B、A分別代表各通道的數值,而下標第一個表示行號,第二個表示列號。即第k行,第j列的G通道數值就是Gkj。
我們很容易得到對於一個Mat類型的mat來說,第k行,第j列像素的每個元素分別是:
Rkj = mat.data[(k * mat.col + j) * 4 + 0]
Gkj = mat.data[(k * mat.col + j) * 4 + 1]
Bkj = mat.data[(k * mat.col + j) * 4 + 2]
Akj = mat.data[(k * mat.col + j) * 4 + 3]

Buffer部分引用方法
通過Buffer的部分引用,我們可以得到矩陣的部分引用,比如我們可以利用這個來擷取一個像素點的資料數組,而改變這個數組中的值,相應的矩陣資料也會改變;再比如我們可以以其他資料類型的方式讀取資料。而這些對於普通Array是不能實現的。下面我們來看一下at方法的實現: 複製代碼 代碼如下:Mat.prototype.at = function(__type, __x, __y){
var type = __type,
x = __x || 0,
y = __y || 0,
rowLen = this.col * this.channel * this.bytes,
len = 1;
if(type.indexOf("Vec") > -1){
var temp = __type.match(/Vec(\d+)([a-z])/);
len = parseInt(temp[1]);
switch(temp[2]){
case "b":
type = "uchar";
break;
case "s":
type = "short";
break;
case "i":
type = "int";
break;
case "f":
type = "float";
break;
case "d":
type = "double";
break;
}
}
switch(type){
case "uchar":
return new Uint8Array(this.buffer, (y * rowLen + x), len);
break;
case "short":
return new Int16Array(this.buffer, (y * rowLen + x * 2), len);
break;
case "int":
return new Int32Array(this.buffer, (y * rowLen + x * 4), len);
break;
case "float":
return new Float32Array(this.buffer, (y * rowLen + x * 4), len);
break;
case "doulble":
return new Float64Array(this.buffer, (y * rowLen + x * 8), len);
break;
default:
console.error("不支援資料類型");
}
};

如果你對ArrayBuffer和TypedArray還不太清楚,可以參考:HTML5 中的新數組。
String type - 需要返回的資料類型。支援:
uchar 無符號8位整數
short 有符號16位整數
int 有符號32位整數
float 有符號32位浮點數
double 有符號64位浮點數

Vec 向量形式
向量形式字串拼字是:Vec + (類型)+ (個數),例如Vecb4就是4個無符號8位整數,這是常見的得到一個像素點資料的方法,例如為了得到mat第j行,第k列的像素資料,可以使用: 複製代碼 代碼如下:mat.at("Vecb4", j, k);

int x - 要擷取的元素在矩陣的行數。
int y - 要擷取的元素在矩陣的列數。

getRow方法和getCol方法
類似於at的實現方法,我們可以很容易寫出擷取某一行或者某一列的方法: 複製代碼 代碼如下:Mat.prototype.getRow = function(__i){
var len = this.col * this.channel,
rowLen = len * this.bytes,
i = __i || 0;
return new this.data.constructor(this.buffer, i * rowLen, len);
};

複製代碼 代碼如下:Mat.prototype.getCol = function(__i){
var len = this.col * this.channel,
rowLen = len * this.bytes,
array = [],
i = __i || 0;
function getAllElement(__constructor){
var row = this.row,
channel = this.channel;
for(var j = 0; j < row; j++){
array.push(new __constructor(this.buffer, j * rowLen + i, 1 * channel));
}
}
getAllElement(this.data.constructor);
return array;
};

rowRange和colRange方法
類似的,我們也可以得到指定行和指定列的方法: 複製代碼 代碼如下:Mat.prototype.rowRange = function(__i, __j){
var len = this.col * this.channel,
rowLen = len * this.bytes,
array = [],
i = __i || 0,
j = __j || this.row;
function getAllElement(__constructor){
var row = this.row;
for(var k = i; k <= j; k++){
array.push(new __constructor(this.buffer, k * rowLen, len));
}
}
getAllElement(this.data.constructor);
return array;
};

複製代碼 代碼如下:Mat.prototype.colRange = function(__i, __j){
var len = this.col * this.channel,
rowLen = len * this.bytes,
array = [],
i = __i || 0,
j = __j || this.col;
function getAllElement(__constructor){
var row = this.row
channel = this.channel;
for(var k = 0; k < row; k++){
array.push(new __constructor(this.buffer, k * rowLen + __i, (__j - __i + 1) * channel));
}
}
getAllElement(Float64Array);
return array;
};

這四種方法返回的都是一種Array<TypedArray>的數組。如果要擷取這個數組rect第j行,第k列的元素,則可用:
rect[j][k]

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.