区域医疗移动医疗影像基于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图像处理

区域医疗移动医疗影像基于HTML5的PACS--HTML5图像处理(6)图像叠加变换,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。