標籤:配置 相關 映像縮放 完全 Google翻譯 init 檔案夾 提示 開發
上一篇簡單介紹了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;
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滑鼠移動量對應的不是圖片移動的距離,先跨一步,然後回來說這個移動量的問題[email protected]。
通過使用 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個多小時,我發現寫隨筆,可以一邊寫一邊梳理當時的思路。
還有一點:使用時需要配置這兩個指令碼路徑,如下。Google翻譯,大概懂意思就行
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