這個頁面的程式碼沒跑起來。

直接從資料夾裡開啟 index.html,瀏覽器會攔下 JavaScript 模組,於是你選好一份影像之後,頁面不會有任何反應。改用 http 把這個資料夾提供出去:

powershell -ExecutionPolicy Bypass -File serve.ps1

然後開啟 http://localhost:8080/。

DICOM 閱片器 在瀏覽器裡開啟 .dcm 影像

CT、MR、X 光和超音波,連窗寬窗位、頭資訊和測量一起。

語言: 繁體中文
檢視原始碼
你的影像不會上傳。這裡根本沒有伺服器。

影像的讀取和解碼全由你自己的瀏覽器完成,頭資訊、畫素、窗寬窗位、測量,都是。這一頁的另一頭根本沒有伺服器可以接收診療資訊,這裡的任何一段程式碼想送也送不出去。而且關於這個檔案的一切都不會告訴任何人,病人的姓名不會,檢查內容不會,檔名也不會。

即時檢查: 檢查中…

離線: 檢查中…

別聽我們說。開啟開發者工具,盯著網路面板,然後開啟一份影像。沒有任何一條請求帶著影像、標籤或者檔名。或者乾脆斷網,照樣打得開。

選影像

把整個資料夾一次拖進來,檔案會各自歸回自己的序列,順序也會排好。什麼都不會上傳,也不會往你的檔案裡寫回任何東西。

以 Markdown 檢視

怎麼開啟一個 DICOM 檔案

  1. 選檔案。一個 .dcm 檔案,或者光碟上的整個資料夾。一次 CT 或者 MR 是一層一個檔案,把它們一起拖進來才是把序列重新拼起來的辦法。檔案由瀏覽器直接從你的硬碟讀取,這期間什麼都不會送去任何地方。
  2. 選序列。一次檢查通常有好幾套,先是定位像,然後是每一次採集。每一套都按裝置拍攝的順序疊好,而這個順序不是從編號來的,是從每一層在身體裡的位置算出來的。編號不一定總朝同一個方向排。
  3. 調窗。這是讓影像變得可讀的那個操作,也是影像編輯軟體沒有的那個。在圖上橫著拖,窗就變寬,上下拖,窗心就移動。CT 還可以直接選帶名字的窗,肺窗、骨窗、腦窗、軟組織窗。CT 的單位在全世界任何一臺機器上都一樣。
  4. 翻層。圖下面那條滑桿在層與層之間移動,在圖上點一下之後,方向鍵也是同樣的效果。多幀檔案,比如超音波的一段迴圈、一次血管造影,用旁邊那個按鈕播放。
  5. 量點什麼。切到測量,拉一條線。檔案寫了畫素間距的,答案就是毫米,而且不是正方形的畫素也會照顧到。檔案沒寫的,答案就是畫素數,並且會明說,不會自己編一個比例出來。
  6. 讀頭資訊。檔案裡的每一個元素,連編號、標準給它的名字和裡面的內容一起,都可以搜尋。它上面是這一份檔案裡究竟什麼在指認病人的清單,而那遠不止一個姓名。
  7. 把需要的帶走。螢幕上那一幀存成 PNG,保留你調好的窗,上面不燒任何字;或者把整份頭資訊存成純文字。兩樣都是在這一頁裡用已經在頁面上的東西拼出來的。

說得更細的版本

怎麼開啟一個 DICOM 檔案,以及裡面有什麼 醫院給的光碟裡都有什麼,檔案為什麼沒有字尾,怎麼在瀏覽器裡開啟一份 .dcm 影像,窗寬窗位到底在做什麼,以及一份影像除了影像之外還帶著關於病人的哪些東西。

常見問題

我的影像會被上傳嗎?

不會。檔案的讀取、解碼和繪製全都由你自己的瀏覽器在你自己的硬體上完成。這個工具根本沒有伺服器那一半,頁面的 Content-Security-Policy 裡寫著它能聯絡的每一個地址,沒有一個屬於本站。把網線拔了,它照樣開啟影像。

這件事在這裡比在本站任何一頁都重要。DICOM 檔案的頭資訊裡帶著病人的姓名、出生日期和住院號,所以把它傳到某個閱片器,等於把一份病歷交給陌生人,而不是一張圖片。

它能開啟哪些 DICOM 檔案?

三種基本 transfer syntax 的未壓縮檔案,也就是 implicit 和 explicit littleendian,加上那個已經廢止的 big endian。此外還有 deflated、RLE Lossless、baseline JPEG 和 JPEG Lossless,醫院光碟上的 CT 和 MR 檢查大多用的是最後這種。

它解不了 JPEG 2000、JPEG-LS,也解不了影片用的 MPEG 和 HEVC 那幾種。那些需要好幾 MB 的編譯庫,而一個用到時才去下載的頁面,就不再是斷網能用的頁面了。這類檔案照樣打得開,整份頭資訊會讀出來顯示,影像的位置換成一行字寫明是哪個編解碼器,而不是一個什麼都說不出的破圖示。

什麼是「窗寬窗位」,為什麼需要它?

一層 CT 裡大約有四千個不同的數值,你的螢幕只能顯示兩百五十六級灰。總得有什麼來決定這四千裡哪一段吃下全部這兩百五十六級,這個選擇就是窗。比它低的全黑,比它高的全白,中間那一段鋪滿灰階。

同一個檔案在兩種設定下看起來像兩次檢查,原因就在這裡,肺和骨沒法同時看清也是。CT 上的數值是亨氏單位,是絕對定義的,水是 0,空氣是 −1000,全世界每一臺 CT 都如此。所以這一頁上那些帶名字的窗,和放射科醫生在工作站上用的是同一批數字。MR 和超音波沒有這樣的標度,開啟時用的是檔案自己要求的那個窗。

為什麼它說我的測量結果是畫素?

因為那個檔案沒寫一個畫素有多大。寫這個的是 Pixel Spacing (0028,0030),單位是毫米,而很多超音波影像、掃描檔和 secondary capture 乾脆就沒有這一項。

有的時候,測量結果是毫米,而且每個方向按自己的間距算,這在畫素不是正方形的圖上很要緊。沒有的時候,老實的答案就是畫素數,它也照實說,而不是挑一個比例把結果當成長度端出來。

它把我的資料夾分成了好幾套序列,為什麼?

因為裡面本來就是這樣。一次檢查由若干序列組成,先是定位像,然後是每一次採集或者重建,每一個檔案都在 Series Instance UID (0020,000E) 裡寫明自己屬於哪一套。那個下拉選單是照這個建的,不是照資料夾建的,資料夾裡通常就是一堆名字混在一起。

在一套序列內部,層的順序按每一層在身體裡的位置排,這個位置來自 Image Position 和 Image Orientation。Instance Number 是最順手的那把鑰匙,但它是備選而不是首選。它由寫這些檔案的東西分配,沒有理由跟病人的方向一致。

「什麼在指認病人」這份清單是什麼意思?

是你檔案裡每一個點名影像中那個人、或者縮小他可能是誰的欄位,都在你的機器上從這一個檔案裡讀出來。清單的依據是 DICOM 標準的 PS3.15,也就是規定一份資料集要能被稱作去標識化之前,必須先去掉什麼的那一部分。

它之所以在這裡,是因為人們弄錯的不是「影像裡有個姓名」這件事,而是裡面還有多少別的。出生日期、檢查號、開單醫生、機構、裝置序列號,還有檢查的那幾個 UID,而 UID 是回到出片檔案庫的完美鑰匙。一份只抹掉姓名的影像並不匿名。

這個工具只給你看。它什麼都不寫,什麼都不改,所以它也拿不掉其中任何一項。

它能把影像匿名化嗎?

不能,而且它故意不裝作能。這一頁只讀,裡面沒有一行程式碼會寫 DICOM 檔案。它做的是告訴你你那份檔案裡到底有什麼,而這恰恰是難查清、又常被弄錯的那一半。

真要把這些標識拿掉,是另一件門檻高得多的工作。它得在不碰畫素的前提下重寫檔案,把整次檢查裡的 UID 一致地替換掉,還得在某些裝置偷偷藏了第二份姓名的私有元素上判斷正確。那件事寫在本站的路線圖裡,不是貼在閱片器上順手做的。

沒有 .dcm 字尾的檔案,或者壞掉的檔案,它打得開嗎?

都打得開。字尾根本不看,看的是檔案本身。有些資料集寫的時候沒有那慣常的 128 位元組前導,直接從網路上取下來的影像就是這個樣子,那就從第一個元素推斷出它的編碼方式來讀,頁面也會寫明它是這麼做的。

中途斷掉的檔案,讀到哪裡算哪裡。損壞之前的部分全部顯示出來,並註明它停在第幾個位元組。恰恰是這種時候最需要閱片器,所以為了最後十二個位元組就把整個檔案扔掉,那才是錯的做法。

這是診斷用的閱片器嗎?

不是。它不是醫療器械,沒有經過任何監管評估,這裡的任何東西都不該拿來做臨床判斷。你的螢幕沒有校準,瀏覽器不是經過驗證的渲染鏈路,這兩件事都不是一個網頁從內部能解決的。

但人們開啟影像的其他所有理由,它都夠用:看看光碟裡有什麼,取一層放進課件或者論文,讀頭資訊,弄清另一個程式為什麼拒收這個檔案,以及看清一份影像究竟帶著關於那個人的多少東西。

它會改我的檔案嗎?

不會。這個工具只讀。沒有輸出檔案,沒有重新編碼,這裡也沒有一個按鈕會寫出 DICOM。你能下載的是螢幕上那一幀的 PNG,和頭資訊的純文字副本。原件原封不動地留在你的硬碟上。

免費嗎?要註冊嗎?

免費,沒有帳號,不用登入,也沒有試用期。檔案多大、開多少個都沒有限制,除了你自己機器的記憶體。本站靠廣告養活,廣告那邊拿不到關於你檔案的任何東西。

斷網能用嗎?

能。把頁面載入一次,然後斷網,它照樣能用。這也是證明什麼都沒被上傳的最簡單辦法。要是有個工具把你的影像送出去讓別人畫,拔掉網線的那一刻它就停了。