上一篇簡單介紹了cornerstone.js的相關使用介紹和基於cornerstone的web庫cornerstoneWADOImageLoader,在實際開發中遇到了相關的一些問題,在這裏說明一下,也是防止之後再次遇到類似的問題,以便查看。javascript
對於一些外部庫,咱們不瞭解實現的每個細節,因此說就有可能遇到各類各樣的坑,經過使用cornerstoneWADOImageLoader庫文件,我從中經過爬"坑"體會到了一個道理:儘可能不要依賴庫自帶變量。見代碼:
java
/* 假設須要獲取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圖像,還須要在畫布上作一些操做git
縮放平移選取:github
上圖左邊是原始圖片,中間是縮放平之後的圖片,右是縮放平移後選取的圖片(這是一張肺部ct圖,圖中紅色的圈是對結節的手動標註)web
座標轉換的問題來了:第三張圖中,紅色圓圈的實現方式很簡單,就是在canvas上繪製紅色的點,而後連起來,簡單的一個畫筆功能。那麼問題是,當圖像縮放平移後,如何得知畫筆相對於圖像的座標?算法
設麼意思呢?:請理解第三張圖,假設圖中紅色的點座標是(160,320),---圖中紅圈是由n個點組成的,咱們假設他一個點的座標,只要求出一個點的座標轉換方法,其餘的也同樣。那麼不管圖片怎麼動,這個點的座標都是(160,320),他是至關Canvas的座標,(點是繪製在canvas上,圖片也是繪製在canvas上,不管圖片怎麼移動,點是不會動的。)那麼當用戶在放大平移這張圖片之後,找到了一個病變的地方,圈出來,那麼如今想要獲取這個紅圈在原圖上的位置,就要進行座標轉換。若是不理解換一種思路,在你的電腦上查看一張圖片或者照片,如今拖動照片窗口的位置,而後放大照片或縮小照片,如今拿左手手指點住顯示屏,點中你要關注的點,不要拿開,右手使用鼠標把敞口和圖片還原到原來的位置大小,那麼你如今的手指還在你點中的位置上麼?這就是座標轉換,咱們的需求是醫生在查看Dicom圖像,手動標註圖像的可疑位置,而後咱們還原紅圈經過算法檢測醫生標註的是否正確,這就是座標轉換的初衷canvas
直接給出公式:(pos.x-(imgX+(cv1.width/2-img.width*scale/2)))/scale;api
@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服務器上託管這兩個文件,並提供一個路徑。