上一篇简单介绍了cornerstone.js的相关使用介绍和基于cornerstone的web库cornerstoneWADOImageLoader,在实际开发中遇到了相关的一些问题,在这里说明一下,也是防止以后再次遇到相似的问题,以便查看。

对于一些外部库,我们不了解实现的每一个细节,所以说就有可能遇到各种各样的坑,通过使用cornerstoneWADOImageLoader库文件,我从中通过爬"坑"体会到了一个道理:尽量不要依赖库自带变量。见代码:

  /*
假设需要获取cornerstoneWADOImageLoader中imagepath的值
在自己的程序中可能多次需要调用这个path值
*/ /*第一种可能bug的写法*/ var path1=cornerstoneWADOImageLoader.imagepath;
...
var path2=cornerstoneWADOImageLoader.imagepath;
... 这种写法出现bug的次数比较多,不一定每次都有bug,因为可能跟调用的变量上下文环境有关,a变量调用没有什么限制条件,b变量也许会有一些上下文限制条件(当然这种情况很少,
但是遇到过bug),或一些其他的限制条件。 /*避免bug的写法很简单*/
var path=cornerstoneWADOImageLoader.imagepath;//定义全局
..
var path1=path;
..
var path2=path;
..
自定义变量接收cornerstoneWADOImageLoader的变量,这样不仅可以避免bug,也可以优化一些性能。我在项目中多次遇到这个bug,第一种写法的时候,明明上边某一行代码调用变量成功了,在下文
在使用这个变量的时候偶尔就会出现无法获取变量的提示。
  • 坐标转换

实际需求,不仅仅是显示Dicom图像,还需要在画布上做一些操作

缩放平移选取:

上图左边是原始图片,中间是缩放平以后的图片,右是缩放平移后选取的图片(这是一张肺部ct图,图中红色的圈是对结节的手动标注)

坐标转换的问题来了:第三张图中,红色圆圈的实现方式很简单,就是在canvas上绘制红色的点,然后连起来,简单的一个画笔功能。那么问题是,当图像缩放平移后,如何得知画笔相对于图像的坐标?

设么意思呢?:请理解第三张图,假设图中红色的点坐标是(160,320),---图中红圈是由n个点组成的,我们假设他一个点的坐标,只要求出一个点的坐标转换方法,其他的也一样。那么无论图片怎么动,这个点的坐标都是(160,320),他是相当Canvas的坐标,(点是绘制在canvas上,图片也是绘制在canvas上,无论图片怎么移动,点是不会动的。)那么当用户在放大平移这张图片以后,找到了一个病变的地方,圈出来,那么现在想要获取这个红圈在原图上的位置,就要进行坐标转换。如果不理解换一种思路,在你的电脑上查看一张图片或者照片,现在拖动照片窗口的位置,然后放大照片或缩小照片,现在拿左手手指点住显示屏,点中你要关注的点,不要拿开,右手使用鼠标把敞口和图片还原到原来的位置大小,那么你现在的手指还在你点中的位置上么?这就是坐标转换,我们的需求是医生在查看Dicom图像,手动标注图像的可疑位置,然后我们还原红圈通过算法检测医生标注的是否正确,这就是坐标转换的初衷

直接给出公式:(pos.x-(imgX+(cv1.width/2-img.width*scale/2)))/scale;

@2017.12.21备注

当初写这章博客的时候,画布的尺寸设计了原始尺寸512*512,所以在坐标转换的问题上没有那么多可能出现的问题,新版本改进后,画布的尺寸是自适应屏幕的,然后今天在写的过程中直接套用了公式,把img.width也设置了画布的尺寸,最后有进行了一个(scale_n=512/cv.width)的缩放调整,结果各种bug。写在这里强调一下,也是为了以后看的时候长有个参考:cv1.width不用说就是当前画布的尺寸,img.width是原始图片的宽度。按照公式套不用再做任何转换直接是正确结果。

pos.x是点的x坐标,imgX是鼠标x方向移动量,cv1是画布,img是图片,scale缩放比例,公式给出了x的转换,对于y的转换直接改成对应y值即可,然后width要改成height,这样就可以通过鼠标点击的点,转换到原图上对应的点,说了这么多,不是主题。。。。。只是正好介绍一下坐标转换,公式可以用于其他任何相关操作的开发项目。

要说的主题是:cornerstone的viewpoint的viewport.translation属性,我们在自定义画布上,可以获取到鼠标移动量,在使用cornerstoneWADOImageLoader这个库,它只需要你提供一个div,它自动会在这个div上创建canvas(目前都是512的)然后绘制,所以说你根本无法获取到canvas的属性,但是他提供了api,可以直接使用,但是有坑。

看代码:

  else   if(3 == e.which)
{ //判断是否为右键
console.log(3);
lastX = e.clientX;
lastY = e.clientY;
$(document).mousemove(function (e) {
deltaX = e.clientX - lastX,
deltaY = e.clientY - lastY;
lastX = e.clientX;
lastY = e.clientY; viewport = cornerstone.getViewport(element);
viewport.translation.x += (deltaX / viewport.scale);
viewport.translation.y += (deltaY / viewport.scale);
// viewport.translation.x += deltaX ;
viewportX=viewport.translation.x; // viewport.translation.y += deltaY ;
viewportY=viewport.translation.y;
console.log(viewportX);
console.log(viewportY);
cornerstone.setViewport(element, viewport);
});

  当鼠标右键点击时,默认对图片操作平移功能。

注意这个变量 viewport.translation.x,这就是他提供的默认的图像移动属性,通过+=鼠标移动量,从而对让图像平移,注意代码注释的部分,最开始我的实现方式是:

// viewport.translation.x += deltaX,这才是真正正确的操作方法

平时在canvas移动图像的步骤是:1.获取鼠标移动量  2.计算图片的起始位置+鼠标移动 3.清空画布,然后根据2算出的位置重新绘制drawimage(),现在这个库给出了translation的属性,无需上述复杂操作(也操作不了,无法获取画布),直接赋值。但是按照常规的算法// viewport.translation.x += deltaX,图片完全可以移动,没有问题,鼠标和图片的相对位置可就不一样了:

截图的时候截不到鼠标图标,我就根据位置自己画了一个,红色的箭头(两次我都是点在图片上,然后进行平移)

左图是使用viewport.translation.x += (deltaX / viewport.scale),可以看到鼠标的位置还是在图片上,相对位置并没有改变。

右图是使用viewport.translation.x += deltaX,鼠标我开始也是点在图片上向右拖动的,但是图片向右移动量大于鼠标移动量,造成了图中的现象,图片走的多了。此时,图片的移动量,根本就不是鼠标的移动量,坐标转换种的imgX鼠标移动量对应的不是图片移动的距离,先跨一步,然后回来说这个移动量的问题--@1。

通过使用 viewport.translation.x += (deltaX / viewport.scale),那么对应的坐标转换公式:

(pos.x-(viewportX*viewport_Scale+(cv1.width/2-img.width*viewport_Scale/2)))/viewport_Scale

公式中viewportX=viewport.translation.x,我自定义了变量赋值,就是上文提到的,我在这里直接使用viewport.translation.x,就报错了,无法获取,然后我用其他变量接受了一下。这不是重点

viewportX*viewport_Scale这个才是重点

上文中,/scale,下面公式又*scale,不是没有改变吗?

因为,原公式是没有*scale的 ,转换公式这里只是imgX

解释:公式的大体思路是:鼠标拖动图片向右移动了50px,那么我在此时标注红圈,那么如果要获取红圈相对于原图的位置,我的红圈要向左-50px,才对,对的就是这个思路,但是,这里鼠标的移动量等于图片的移动量,这也就是@1的问题所在,对于它的api,没有/scale的话,鼠标移动的距离根本不是图片移动的距离,小于图片移动的距离(多少取决于scale),也就是鼠标向右移动了50px,实际图片移动了60px,那么你在用红圈的点-50px,得到的并不是实际相对于图片的位置

以上种种也就是/scale的原因,至于为什么/scale,而不是/scale*2,而不是/scale*3?这要看它的translation的api是怎么定义的,我是在他官方的例子中找到的答案,所以在这里/scale,在下文在乘以scale,确保公式的定义的鼠标移动量。

先保证图片和鼠标同步移动,然后再使用公式。

说了好多,写的1个多小时,我发现写随笔,可以一边写一边梳理当时的思路。

还有一点:使用时需要配置这两个脚本路径,如下。谷歌翻译,大概懂意思就行


Web工作者框架需要一些配置,因为Web工作者需要源文件的路径。由于基石并不执行源文件位置的约定,您必须告诉基础Web工作者框架,其中web worker文件是可以正确加载的。这是通过cornerstoneWADOImageLoader.webWorkerManager.initialize()函数完成的。您必须先调用此函数,然后才能启动Web工作任务(或使用基石加载映像),以使Web工作者代码正确加载。

最小配置

以下是最小配置对象的示例。

   var config = {
webWorkerPath : ' ../../ dist / cornerstoneWADOImageLoaderWebWorker.js ',
taskConfiguration : {
' decodeTask ' : {
codecsPath : ' ../ dist / cornerstoneWADOImageLoaderCodecs.js '
}
}
};
cornerstoneWADOImageLoader。webWorkerManager。initialize(config);

在上面的示例中,您将看到两个路径,一个到cornerstoneWADOImageLoaderWebWorker.js,一个到cornerstoneWADOImageLoaderCodecs.js文件。这两个文件都可以在该存储库的dist文件夹中找到。您必须在您的Web服务器上托管这两个文件,并提供一个路径。

基于cornerstone.js的cornerstoneWADOImageLoader的更多相关文章

  1. 基于cornerstone.js的dicom医学影像查看浏览功能

    最近由于项目需求,需要医学影像.dcm文件的预览功能,功能完成后,基于原生Demo做一个开源分享. 心急的小伙伴可以先看如下基于原生js的全部代码: 一.全部代码 <!DOCTYPE html& ...

  2. Cornerstone.js使用相关

    官网地址:https://github.com/chafey/cornerstone 简介: Cornerstone is an open source project with a goal to ...

  3. 使用医学影像开源库cornerstone.js解析Dicom图像显示到HTML中

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 基于 React.js + Redux + Bootstrap 的 Ruby China 示例 (转)

    一直学 REACT + METEOR 但路由部分有点问题,参考一下:基于 React.js + Redux + Bootstrap 的 Ruby China 示例 http://react-china ...

  5. 用jQuery基于原生js封装的轮播

    我发现轮播在很多网站里面都用到过,一个绚丽的轮播可以为网页增色不少,最近闲来无事,也用原生js封装了一个轮播,可能不像网上的插件那么炫,但是也有用心去做.主要用了闭包的思想.需要传递的参数有:图片地址 ...

  6. 基于Three.js的360X180度全景图预览插件

    基于Three.js的360X180度全景图预览插件 时间 2015-08-12 10:01:10  HTML5中国 原文  http://www.html5cn.org/article-8621-1 ...

  7. NodeBB – 基于 Node.js 的开源论坛系统

    NodeBB 是一个更好的论坛平台,专门为现代网络打造.它是免费的,易于使用. NodeBB 论坛软件是基于 Node.js 开发,支持 Redis 或 MongoDB 的数据库.它利用 Web So ...

  8. RSuite 一个基于 React.js 的 Web 组件库

    RSuite http://rsuite.github.io RSuite 是一个基于 React.js 开发的 Web 组件库,参考 Bootstrap 设计,提供其中常用组件,支持响应式布局. 我 ...

  9. 基于 Node.js 平台,快速、开放、极简的 web 开发框架。

    资料地址:http://www.expressjs.com.cn/ Express 基于 Node.js 平台,快速.开放.极简的 web 开发框架. $ npm install express -- ...

随机推荐

  1. POJ 3171

    题目大意:        给定一个区间范围[M,E],接下来有n行输入.每行输入三个数值:T1,T2,S,表示覆盖区间[T1,T2] 的代价为S,要求你求出覆盖区间[M,E]的最小代价,假设不能覆盖, ...

  2. python学习笔记(二十五)重写父类方法

    python继承中,如果子类在调用某个方法时,它首先是从派生类(也就是当前类)中去找对应的方法,如果当前类中找不到对应的方法,就会去基类(派生类)中去逐个查找. 若父类的方法不能满足子类的需要,那么子 ...

  3. a=a+1背后的内存模型和CPU高速缓存

    学过JAVA的人都知道,程序运行过程中的临时数据,都是从外部存储设备调入内存(物理内存)中,再进行读写操作的.而计算机在执行程序时,对程序的每条指令都是在CPU中执行的,而指令的执行,势必涉及到对数据 ...

  4. 模块讲解----json与pickle模块的区别

    1.在生产中,dumps和loads只进行一次,而且要用w把原来的数据冲掉,从而保证每次都是最新的. 2.虚拟机的快照,是每个快照都有一个文件,而不是全都不放在一起. 3.如果想生产好几个序列化,就生 ...

  5. SQL Server 使用触发器(trigger)发送电子邮件

    sql 使用系统存储过程 sp_send_dbmail 发送电子邮件语法: sp_send_dbmail [ [ @profile_name = ] 'profile_name' ] [ , [ @r ...

  6. ruby中的instance_eval,class_eval,eval

    ruby具有在运行时执行以字符串形式保存的代码的功能设施,eval族方法 .包括Kernel#eval,Object#instance_eval,Module#class_eval. Kernel#e ...

  7. 一个辅助AWVS C段扫描的小php脚本

    小菜写的小脚本,大牛轻拍砖~~~~~~ 渗透前信息收集时喜欢用椰树来获取旁站及二级域名,然后根据二级.三级域名地址扩展C段,扩大扫描业务边界.例如 以联想为例 但,各个旁站对应IP可能不同,或有CDN ...

  8. c调用c++编的dll,c++调用c编写的dll,extern “C”的用法

    转自:http://blog.csdn.net/life_is_too_hard/article/details/52137271 c和c++不能直接相互调用,主要是因为c++有重载函数的功能,为了区 ...

  9. Http:UTF-8与GB2312之间的关系

    UTF-8里包括GB2312.UTF-8是国际通用的标准(包括世界所有的语言),而GB2312(只是简体中文)只适合做中文的网站.假设你想做个中文网页,但是还可以翻成英文的话,就得用UTF-8.如果用 ...

  10. goquery常用语法

    Find 查找获取当前匹配的每个元素的后代Eq 选择第几个Attr 获取对应的标签属性AttrOr 获取对应的标签属性.这个可以设置第二个参数.获取的默认值 如果获取不到默认调用对应默认值Each 遍 ...