一整套 PET-CT 檢查:OHIF 零足跡 DICOM 查看器實(shí)現(xiàn)筆記)
零部署打開(kāi)一整套 PET-CT 檢查OHIF 零足跡 DICOM 查看器實(shí)現(xiàn)筆記【免費(fèi)下載鏈接】ViewersOHIF zero-footprint DICOM viewer and oncology specific Lesion Tracker, plus shared extension packages項(xiàng)目地址: https://gitcode.com/GitHub_Trending/vi/Viewers放射科醫(yī)生點(diǎn)開(kāi)一個(gè) DICOM Web 鏈接幾秒后屏幕出現(xiàn)配準(zhǔn)好的 PET-CT軸位、代謝圖、融合三層同步聯(lián)動(dòng)——這是零足跡 DICOM 查看器 OHIF 在瀏覽器里做的事。它面向醫(yī)院和科研機(jī)構(gòu)不裝客戶端影像直接跑在瀏覽器里功能按擴(kuò)展組織、按需組合。零足跡 DICOM 查看器的骨架mode 聲明布局extension 提供能力倉(cāng)庫(kù)是一個(gè) pnpm monorepoplatform/core/ 是宿主extensions/ 是能力包modes/ 是可直接用的組合。宿主定義的 Extension 接口非??酥苝reRegistration、onModeEnter/onModeExit兩個(gè)生命周期鉤子加一組getXxxModule——viewport、panel、toolbar、commands、customization、sopClassHandler、hangingProtocol各擴(kuò)展按需填。我注意到一個(gè)有意思的取舍mode 并不直接 import 擴(kuò)展而是聲明一張依賴表。modes/basic/src/index.tsx 里寫(xiě)著extensionDependencies: { ohif/extension-cornerstone: ^3.0.0, ... }——語(yǔ)義上等價(jià)于 peerDependencies插件與宿主約定最低版本實(shí)際解析交給宿主。同文件里 sopClassHandlers 列表的順序也有講究video handler 刻意排在圖像 handler 之前注釋直接解釋了原因先剝離 video 傳輸語(yǔ)法再讓通用 handler 接手。組合的威力在 modes/longitudinal/ 更明顯它不重寫(xiě)布局只繼承 basic 的 layout然后把視口和側(cè)欄換成被追蹤版本。宿主出服務(wù)容器和事件總線擴(kuò)展出能力mode 決定長(zhǎng)什么樣——三層分工到此清晰。骨架搭好之后先看一幀數(shù)據(jù)怎么穿過(guò)這套骨架。瀏覽器醫(yī)學(xué)影像的一幀數(shù)據(jù)鏈路從 DICOM Web 響應(yīng)到上屏一幀 CT 的上屏路徑分四段每段都有明確歸屬。第一段取數(shù)extensions/default/ 里的 DicomWebDataSource 負(fù)責(zé)與影像歸檔走 QIDO/WADO-RS也支持多源合并和本地文件。第二段歸組系列元數(shù)據(jù)交給 sopClassHandler 按 SOP Class 拆成 display set——stack、SR、PDF、video 各有各的 handler這是整個(gè)查看器什么都能看的調(diào)度點(diǎn)。第三段加載display set 里每幀的 imageId 攜帶了數(shù)據(jù)源信息而加載器是按名字注冊(cè)的——registerVolumeLoader( cornerstoneStreamingImageVolume, cornerstoneStreamingImageVolumeLoader );見(jiàn) initWADOImageLoader.js注冊(cè)了兩個(gè)流式 volume loader實(shí)際取幀和解碼委托給cornerstonejs/dicom-image-loader編解碼走對(duì)應(yīng) WASM codec。值得說(shuō)的是擴(kuò)展把四個(gè) codec 都釘在 peerDependencies 里而非自身依賴——解碼能力被當(dāng)成基礎(chǔ)設(shè)施契約而不是擴(kuò)展細(xì)節(jié)。CornerstoneCacheService 也掛在這條鏈上把 cornerstone 內(nèi)部圖像緩存的占用與剩余空間暴露給 UI讓內(nèi)存還剩多少變得可見(jiàn)。單幀走通后下一個(gè)問(wèn)題是多個(gè)視口怎么不打架。MPR 三個(gè)切面和 3D 體怎么保持同步上面是文檔里的演示截圖左側(cè)軸、冠、矢三個(gè)切面與右上 3D VR 共享同一個(gè)體積十字光標(biāo)隨滾動(dòng)聯(lián)動(dòng)。同步的實(shí)現(xiàn)比想象中少。frameViewSynchronizer 訂閱 STACK_VIEWPORT_SCROLL 與 CAMERA_MODIFIED 事件任一視口滾動(dòng)時(shí)其余按目標(biāo) slice 源 slice 索引差跟隨——即各平面保持固定片差而非絕對(duì)對(duì)齊。這個(gè)選擇讓多時(shí)間點(diǎn)比較不同檢查的對(duì)應(yīng)層號(hào)往往不一致比硬對(duì)齊好處理得多。3D 一側(cè)依賴 vtk.jscornerstone 擴(kuò)展的依賴?yán)镉衚itware/vtk.js 36.4.1。體積不是一次性下載完成的onModeEnter里為 volume 注冊(cè)了交錯(cuò)漸進(jìn)式取幀interleaved retrieve stages源碼注釋原話是先復(fù)現(xiàn)一個(gè)低分辨率深度體積重建再逐步提精。用戶看到的是體素質(zhì)量一點(diǎn)點(diǎn)漲上來(lái)而不是一片黑等 loading。同步只是表面底下的瓶頸是數(shù)據(jù)量本身。把 GB 級(jí)數(shù)據(jù)馴進(jìn)瀏覽器WASM 編解碼、Worker 池與流式加載瓶頸在解碼全腦 CT 的壓縮數(shù)據(jù)動(dòng)輒上百 MB。OHIF 不自己寫(xiě)解碼器peerDependencies 里的四個(gè) WASM codeccodec-openjpeg、codec-openjph、codec-libjpeg-turbo-8bit、codec-charls分別覆蓋 JPEG 2000、JPEG-LS、RLE 等醫(yī)學(xué)壓縮格式解碼全部丟進(jìn) Web Worker 池。池子的規(guī)模決策值得一讀同樣在 initWADOImageLoader.jsmaxWebWorkers: Math.min( Math.max(navigator.hardwareConcurrency - 1, 1), appConfig.maxNumberOfWebWorkers )CPU 核數(shù)減一、最少留一個(gè)再受應(yīng)用配置封頂——主線程永遠(yuǎn)不被解碼占滿。取數(shù)側(cè)默認(rèn)流式stack 的默認(rèn)選項(xiàng)是streaming: true, decodeLevel: 1即取一幀解一幀而不是整系列下載完再動(dòng)。內(nèi)存回收也有明確邊界onModeExit會(huì)清空?qǐng)D像加載/取幀隊(duì)列和 Part10 元數(shù)據(jù)緩存源碼注釋寫(xiě)明目的是防止模式切換時(shí)的內(nèi)存泄漏。數(shù)據(jù)層之外最見(jiàn)功力的是垂直場(chǎng)景的處理細(xì)節(jié)。放療規(guī)劃疊加層一個(gè) RTSTRUCT 的輪廓點(diǎn)從哪來(lái)這是演示截圖GTV、PTV、Brain Stem 等十幾個(gè)器官輪廓以不同顏色疊在頭部 CT 上。背后的工作量集中在 extensions/cornerstone-dicom-rt/ 的 loadRTStruct.js輪廓點(diǎn)要兼容三種存儲(chǔ)形態(tài)——直接數(shù)組、InlineBinary base64以及 DICOM Web 場(chǎng)景最常見(jiàn)的 BulkDataURI輪廓點(diǎn)不在文件里要回到歸檔的 bulkdata 端點(diǎn)再取一次。顏色也有兩個(gè)來(lái)源直接的 ROIDisplayColor或把 CIELab 推薦值用 dcmjs 的 dicomlab2RGB 轉(zhuǎn)成 RGB。這類細(xì)節(jié)正是能顯示和顯示得對(duì)的分界線。放療處理的是結(jié)構(gòu)疊加腫瘤隨訪要處理的則是狀態(tài)一致性。病灶追蹤臨時(shí)測(cè)量和永久狀態(tài)之間的一致性modes/longitudinal/ 模式服務(wù)于腫瘤療效評(píng)估核心是一臺(tái)狀態(tài)機(jī)畫(huà)完標(biāo)注后彈出是否追蹤的提示。答是——實(shí)線進(jìn)入右側(cè)測(cè)量面板可導(dǎo)出 DICOM SR答否——虛線只留在圖像上不可導(dǎo)出。這張流程圖來(lái)自該模式的 README真正的復(fù)雜度藏在 SR 導(dǎo)入時(shí)重新載入結(jié)構(gòu)化報(bào)告前先判斷該序列是否已在追蹤。是——SR 只以只讀方式呈現(xiàn)用戶還能調(diào)窗寬窗位、畫(huà)臨時(shí)測(cè)量視口左上角掛鎖形圖標(biāo)否——?dú)v史測(cè)量被重新水合進(jìn)視口全部標(biāo)記為已追蹤。這一個(gè)判斷避免了用戶新測(cè)量和歷史報(bào)告兩個(gè)數(shù)據(jù)源互相覆蓋。旁邊的 modes/tmtv/ 模式是同一套思路的延伸PET-CT 融合上加閾值分割標(biāo)出代謝活躍病灶右側(cè)面板直接給出單灶 SUV 峰值截圖為 25.70、體積與 TMTV 總量 85.93 mL可一鍵導(dǎo)出 CSV 或 RT 報(bào)告。功能看完回到工程現(xiàn)狀。它現(xiàn)在跑得怎么樣beta 線上的雙引擎遷移與 Playwright 回歸基線說(shuō)實(shí)話根 package 版本是 3.14.0-beta.56master 就是 beta 線。代碼里正進(jìn)行一項(xiàng)遷移——新一代 next 視口PLANAR_NEXT與舊引擎并行注釋反復(fù)強(qiáng)調(diào) flag 關(guān)閉時(shí)舊路徑保持字節(jié)級(jí)一致等于把舊實(shí)現(xiàn)釘成回歸基線。測(cè)試側(cè)tests/ 目錄有 80 余個(gè) Playwright spec覆蓋 MPR、SEG 水合、RT 疊加、TMTV 等場(chǎng)景screenshots/下是成套的截圖回歸庫(kù)對(duì)影像項(xiàng)目來(lái)說(shuō)這種視覺(jué)基線相當(dāng)扎實(shí)。邊界也明確零足跡意味著解碼與渲染全在瀏覽器側(cè)完成超大量 4D 序列、全切片影像的吞吐直接受網(wǎng)絡(luò)與 WASM 解碼速度制約幀率上限與其他瀏覽器渲染方案沒(méi)有本質(zhì)區(qū)別。判斷它把 PACS 級(jí)能力拆成宿主、擴(kuò)展、模式三層再拼回瀏覽器測(cè)試基線說(shuō)明成熟度不低。想評(píng)估 DICOM Web 方案可直接跑倉(cāng)庫(kù)的 demo 構(gòu)建連 Orthanc 數(shù)據(jù)源驗(yàn)證實(shí)際鏈路?!久赓M(fèi)下載鏈接】ViewersOHIF zero-footprint DICOM viewer and oncology specific Lesion Tracker, plus shared extension packages項(xiàng)目地址: https://gitcode.com/GitHub_Trending/vi/Viewers創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考