题记:写这篇博客要主是加深自己对方法矩阵的认识和总结现实算法时的一些验经和训教,如果有错误请指出,万分感谢。
言前
上一篇文章,我们义定了矩阵,这篇文章我们来给矩阵添加一些经常使用方法。
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("不支撑数据类型"); } };
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 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; };
rect[j][k]
系列目录
考参资料
文章结束给大家分享下程序员的一些笑话语录: AdobeFlash拖垮Windows拖垮IE!又拖垮Linux拖垮Ubuntu拖垮FirxEox!还拖垮BSD拖垮MacOS拖垮Safri!简直无所不拖!AdobeFlash滚出网路世界!不要以为市占有率高就可以持续出烂货产品!以后替代品多得是!