区域医疗移动医疗影像基于HTML5的PACS--HTML5图像处理(6)图像叠加变换
仅提供参考和学习,代码仅为了指明个思路,转载请注明出处。
要查看此系统更多的图像处理功能请参考:
区域医疗移动医疗影像解决方案--基于HTML5的PACS--HTML5图像处理
HTML5的canvas提供提供了矩阵变换的方法 transform(a, b, c, d, e, f)
和 setTransform(a, b, c, d, e, f)
。其中 setTransform()
它都会重置前一个变换矩阵然后构建新的矩阵。而transform()
方法,它会在前一个变换矩阵上构建,即相对于之前的变换矩阵,起到了变换叠加的效果。但是在实际运用中有时需要记录下当前叠加变换后的矩阵,以方便通过变换矩阵来实现更多的功能。比如说常见的在图像上画线的功能,如果对图像做了变换操作,图像上画的线段也要做相应的变换,这就需要通过变换矩阵来做点的映射。但是canvas方法中并没有相应的getTransform()等方法,javascript中也没有矩阵类这一说法,这不像其它语言一样有现成的Matrix类。所以就需要用javascript来实现一个Matrix类。
transform(a, b, c, d, e, f);和setTransform(a, b, c, d, e, f);方法中提供的6个参数a b c d e f,其使用基本公式是这样的:
其中,x和y是元素最开始的坐标,x’
和y’则是通过矩阵变换后得到新的坐标。
通过中间的那个3×3的变换矩阵,对原先的坐标施加变换,就能得到新的坐标了。
所以只需要构造好中间的3X3矩阵,做图像叠加变换的时候就转移到中间矩阵的乘法运算,把运算结果在赋值给 setTransform(a, b, c, d, e, f)即可。
比如:做了叠加变换transform(a1, b1, c1, d1, e1, f1)和transform(a2, b2, c2, d2, e2,
f2),可以转换成如下的公式:
即做完矩阵运算后我们只需要调用方法setTransform(a3,
b3, c3, d3, e3, f3)即可。
如下是从代码中提炼出的用javascript封装的精简版Matrix。
1 //author http://www.cnblogs.com/poxiao 2 function Matrix(values){//可通过传递用分号分隔的字符串来构造矩阵,如"a,b,c,d,e,f" 3 this.a=1; 4 this.b=0; 5 this.c=0; 6 this.d=1; 7 this.e=0; 8 this.f=0; 9 if(values!=null && values!=undefined){ 10 var arrays=values.split(","); 11 if(arrays.length==6){ 12 this.a=arrays[0]; 13 this.b=arrays[1]; 14 this.c=arrays[2]; 15 this.d=arrays[3]; 16 this.e=arrays[4]; 17 this.f=arrays[5]; 18 } 19 } 20 } 21 //设置变换矩阵 22 Matrix.prototype.setValues=function(arrays){ 23 if(arrays.length==6){ 24 this.a=arrays[0]; 25 this.b=arrays[1]; 26 this.c=arrays[2]; 27 this.d=arrays[3]; 28 this.e=arrays[4]; 29 this.f=arrays[5]; 30 }else if(arrays.length==9){ 31 this.a=arrays[0]; 32 this.b=arrays[3]; 33 this.c=arrays[1]; 34 this.d=arrays[4]; 35 this.e=arrays[2]; 36 this.f=arrays[5]; 37 } 38 }; 39 //设置缩放倍数 40 Matrix.prototype.setScale=function(sx,sy){ 41 this.b=0; 42 this.c=0; 43 this.e=0; 44 this.f=0; 45 46 this.a=sx; 47 this.d=sy; 48 }; 49 //设置平移 50 Matrix.prototype.setTranslate=function(dx,dy){ 51 this.a=1; 52 this.b=0; 53 this.c=0; 54 this.d=1; 55 56 this.e=sx; 57 this.f=sy; 58 }; 59 //设置旋转度数 60 Matrix.prototype.setRotation=function(degree){ 61 //[ cos(degree) -sin(degree) 0 ] 62 //[ sin(degree) cos(degree) 0 ] 63 //[ 0 0 1 ] 64 degree=degree*Math.PI / 180; 65 this.a=Math.cos(degree); 66 this.b=Math.sin(degree); 67 this.c=-Math.sin(degree); 68 this.d=Math.cos(degree); 69 this.e=0; 70 this.f=0; 71 }; 72 Matrix.prototype.toString=function(){ 73 return this.a+","+this.b+","+this.c+","+this.d+","+this.e+","+this.f; 74 }; 75 //矩阵乘法参数 tx 表示Matrix对象, 76 //[this]=[Tx]X[this] 77 Matrix.prototype.postConcat=function(tx){ 78 var v_a=tx.a*this.a+tx.c*this.b; 79 var v_b=tx.b*this.a+tx.d*this.b; 80 var v_c=tx.a*this.c+tx.c*this.d; 81 var v_d=tx.b*this.c+tx.d*this.d; 82 var v_e=tx.a*this.e+tx.c*this.f+tx.e; 83 var v_f=tx.b*this.e+tx.d*this.f+tx.f; 84 85 this.a=v_a; 86 this.b=v_b; 87 this.c=v_c; 88 this.d=v_d; 89 this.e=v_e; 90 this.f=v_f; 91 }; 92 //返回水平方向的平移量 93 Matrix.prototype.getTranslateX=function() { 94 return this.e; 95 }; 96 //返回垂直方向的平移量 97 Matrix.prototype.getTranslateY=function() { 98 return this.f; 99 }; 100 //返回水平方向的倾斜量 101 Matrix.prototype.getShearX=function() { 102 return this.c; 103 }; 104 //返回垂直方向的倾斜量 105 Matrix.prototype.getShearY=function() { 106 return this.b; 107 }; 108 //返回水平方向的缩放量 109 Matrix.prototype.getScaleX=function() { 110 return this.a; 111 }; 112 //返回垂直方向的缩放量 113 Matrix.prototype.getScaleY=function() { 114 return this.d; 115 };
有了这个Matrix后对于上面的叠加变换即可精简为如下的代码:
1 var matrix=new Matrix("a1,b1,c1,d1,e1,f1"); 2 matrix.postConcat(new Matrix("a2,b2,c2,d2,e2,f2")); 3 4 var context=canvas.getContext("2d"); 5 context.setTransform(matrix.a,matrix.b,matrix.c,matrix.d,matrix.e,matrix.f);
额外话:本文中的Matrix只是提供了简单的乘法运算,如果你要做图像测量等功能。还需要实现点的映射方法,矩阵的逆方法等。在此不在叙述,不明白的就回去看下大学的线性代数吧。
系列文章暂时先写到这吧。其实文章对于大神来说没启到多大的作用,大神门看后都会狂喷,也就是简单的思路,给刚入门的想用html5做图像处理的一点小小的提示。
系统实际中的效果图(为了防止别人把图像加以商业宣传,每个图片加上了网址水印望理解)
1原始图
2.测量图
3.对图像进行旋转,移动,放大等图像叠加变换后效果图
查看此系统更多的图像处理功能请参考:
区域医疗移动医疗影像解决方案--基于HTML5的PACS--HTML5图像处理
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。