介紹如何在 Ubuntu Linux 中安裝與設定 Orthanc DICOM 影像伺服器,並以 Restful API 來操控 PACS 系統。
若在 Ubuntu Linux 中,可以透過 apt
安裝 Orthanc 伺服器,而除了基礎的 orthanc
套件之外,亦可選擇性安裝需要的外掛(plugin):
# 安裝 Orthanc 伺服器與相關套件 sudo apt install orthanc orthanc-dicomweb orthanc-imagej \ orthanc-webviewer orthanc-wsi
安裝完成之後,Orthanc 預設會自動啟用,預設的 DICOM 伺服器連接埠為 4242
,而 Orthanc 的網頁介面連接埠則為 8042
,開啟 http://localhost:8042/
這個網址就可以看到 Orthanc 的網頁介面了,在網頁介面中提供了上傳、查詢、顯示與管理 DICOM 影像的各種功能。
管理者可以使用 systemctl
來查看或控制系統上的 orthanc
服務:
# 查看 orthanc 服務狀態 systemctl status orthanc # 啟動 orthanc 服務 sudo systemctl start orthanc # 重新啟動 orthanc 服務 sudo systemctl restart orthanc # 停止 orthanc 服務 sudo systemctl stop orthanc
這裡我們採用 DICOM Library 網站上所提供的 DICOM 影像來示範如何將 DICOM 影像匯入 Orthanc 伺服器中。
假設我們將一個 series 的 DICOM 影像放在 series-000001
目錄中,若要匯入單一 DICOM 檔案,可以使用以下指令:
# 匯入單一 DICOM Instance 檔案 curl -X POST http://localhost:8042/instances --data-binary @series-000001/image-000001.dcm
{ "ID" : "03c9a57e-19836571-d4eefc16-2ad94243-9c8b63e2", "ParentPatient" : "b6589fc6-ab0dc82c-f12099d1-c2d40ab9-94e8410c", "ParentSeries" : "98d367a5-58eeba8b-f3c2da4b-de7d8f6f-ede53eb2", "ParentStudy" : "3abaec0a-ebfaaa87-f830d52b-d62df074-6a692c12", "Path" : "/instances/03c9a57e-19836571-d4eefc16-2ad94243-9c8b63e2", "Status" : "Success" }
在匯入大量 DICOM 影像的時候,可以加上 -H "Expect:"
參數,這樣可以讓 curl
的處理速度大幅增加:
# 匯入單一 DICOM Instance 檔案 curl -X POST -H "Expect:" http://localhost:8042/instances --data-binary @series-000001/image-000001.dcm
若要匯入整個目錄之下的所有 DICOM 影像,可以利用 Orthanc 附帶的 OrthancImport.py
指令稿:
# 匯入目錄下所有 DICOM 檔案
python OrthancImport.py series-000001/
New imported study: Orthanc ID of the patient: b6589fc6-ab0dc82c-f12099d1-c2d40ab9-94e8410c Orthanc ID of the study: 3abaec0a-ebfaaa87-f830d52b-d62df074-6a692c12 DICOM Patient ID: 0 DICOM Study Instance UID: 1.2.826.0.1.3680043.8.1055.1.20111102150758591.92402465.76095170 SUCCESS: 361 DICOM instances properly imported 1 DICOM studies properly imported 0 JSON files ignored Error in 0 files
除了目錄之外,OrthancImport.py
指令稿亦可匯入 .zip
、.tar.gz
或 .tar.bz2
壓縮檔之中的 DICOM 檔案。
若要查詢 Orthanc 伺服器中的 DICOM 資訊,也可以透過 Restful API 來執行,查詢的結果都會以 JSON 格式呈現。
以下是使用 Orthanc 的 Restful API 列出所有 Patients、Studies、Series 與 Instances 的方法:
# 查詢所有 Patients
curl http://localhost:8042/patients
[ "b6589fc6-ab0dc82c-f12099d1-c2d40ab9-94e8410c" ]
# 查詢所有 Studies
curl http://localhost:8042/studies
[ "3abaec0a-ebfaaa87-f830d52b-d62df074-6a692c12" ]
# 查詢所有 Series
curl http://localhost:8042/series
[ "98d367a5-58eeba8b-f3c2da4b-de7d8f6f-ede53eb2" ]
# 查詢所有 Instances
curl http://localhost:8042/instances
[ "03c9a57e-19836571-d4eefc16-2ad94243-9c8b63e2", "08e44aae-2fe82e0b-8119fe02-a096f788-c239fd9a", "1722970d-4c18120f-4e8341ce-68c58668-c3ec19d6", [略] "a1adcd88-1b3d3d3b-17938393-cfa13eb7-73e3a5f1" ]
若要列出指定 Patient 的資訊,可以執行:
# 查詢 Patient 資訊
curl http://localhost:8042/patients/b6589fc6-ab0dc82c-f12099d1-c2d40ab9-94e8410c
{ "ID" : "b6589fc6-ab0dc82c-f12099d1-c2d40ab9-94e8410c", "IsStable" : true, "LastUpdate" : "20220313T121803", "MainDicomTags" : { "PatientID" : "0", "PatientName" : "Anonymized" }, "Studies" : [ "3abaec0a-ebfaaa87-f830d52b-d62df074-6a692c12" ], "Type" : "Patient" }
若要列出指定 Study 的資訊,可以執行:
# 查詢 Study 資訊
curl http://localhost:8042/studies/3abaec0a-ebfaaa87-f830d52b-d62df074-6a692c12
{ "ID" : "3abaec0a-ebfaaa87-f830d52b-d62df074-6a692c12", "IsStable" : true, "LastUpdate" : "20220313T121803", "MainDicomTags" : { "StudyDate" : "20061012", "StudyDescription" : "CT1 abdomen", "StudyInstanceUID" : "1.2.826.0.1.3680043.8.1055.1.20111102150758591.92402465.76095170", "StudyTime" : "090258.000000" }, "ParentPatient" : "b6589fc6-ab0dc82c-f12099d1-c2d40ab9-94e8410c", "PatientMainDicomTags" : { "PatientID" : "0", "PatientName" : "Anonymized" }, "Series" : [ "98d367a5-58eeba8b-f3c2da4b-de7d8f6f-ede53eb2" ], "Type" : "Study" }
若要列出指定 Series 的資訊,可以執行:
# 查詢 Series 資訊
curl http://localhost:8042/series/98d367a5-58eeba8b-f3c2da4b-de7d8f6f-ede53eb2
{ "ExpectedNumberOfInstances" : null, "ID" : "98d367a5-58eeba8b-f3c2da4b-de7d8f6f-ede53eb2", "Instances" : [ "03c9a57e-19836571-d4eefc16-2ad94243-9c8b63e2", "08e44aae-2fe82e0b-8119fe02-a096f788-c239fd9a", "1722970d-4c18120f-4e8341ce-68c58668-c3ec19d6", [略] "a1adcd88-1b3d3d3b-17938393-cfa13eb7-73e3a5f1" ], "IsStable" : true, "LastUpdate" : "20220313T121803", "MainDicomTags" : { "ContrastBolusAgent" : "CONTRAST", "ImageOrientationPatient" : "1\\0\\0\\0\\1\\0", "Modality" : "CT", "PerformedProcedureStepDescription" : "CT1 abdomen", "ProtocolName" : "ART.RENALES 12/Abdomen/Hx", "SeriesDescription" : "ARTERIELLE", "SeriesInstanceUID" : "1.2.826.0.1.3680043.8.1055.1.20111102150758591.96842950.07877442", "SeriesNumber" : "6168" }, "ParentStudy" : "3abaec0a-ebfaaa87-f830d52b-d62df074-6a692c12", "Status" : "Unknown", "Type" : "Series" }
若要列出指定 Instance 的資訊,可以執行:
# 查詢 Instance 資訊
curl http://localhost:8042/instances/03c9a57e-19836571-d4eefc16-2ad94243-9c8b63e2
{ "FileSize" : 91250, "FileUuid" : "d03d7b8b-5761-4620-8032-f14b164c0298", "ID" : "03c9a57e-19836571-d4eefc16-2ad94243-9c8b63e2", "IndexInSeries" : 1, "MainDicomTags" : { "ImageComments" : "JPEG 2000 lossless - Version 4.0.2 (c) Image Devices GmbH", "ImageOrientationPatient" : "1\\0\\0\\0\\1\\0", "ImagePositionPatient" : "-151.493508\\-36.6564417\\1295", "InstanceCreationDate" : "20061012", "InstanceCreationTime" : "091605.000000", "InstanceNumber" : "1", "SOPInstanceUID" : "1.2.826.0.1.3680043.8.1055.1.20111102150758591.03296050.69180943" }, "ParentSeries" : "98d367a5-58eeba8b-f3c2da4b-de7d8f6f-ede53eb2", "Type" : "Instance" }
若要查看指定 Instance 的 DICOM 標籤(tags),可以執行:
# 查看指定 Instance 的 DICOM 標籤(簡易版)
curl http://localhost:8042/instances/03c9a57e-19836571-d4eefc16-2ad94243-9c8b63e2/simplified-tags
{ "AcquisitionDate" : "20061012", "AcquisitionTime" : "085229.000000", "BitsAllocated" : "16", [略] "XRayTubeCurrent" : "400" }
若要更詳細的版本,可以執行:
# 查看指定 Instance 的 DICOM 標籤(詳細版)
curl http://localhost:8042/instances/03c9a57e-19836571-d4eefc16-2ad94243-9c8b63e2/tags
{ "Name" : "SpecificCharacterSet", "Type" : "String", "Value" : "ISO_IR 100" }, "0008,0008" : { "Name" : "ImageType", "Type" : "String", "Value" : "ORIGINAL\\PRIMARY\\AXIAL\\HELIX" }, [略] "7fe0,0010" : { "Name" : "PixelData", "Type" : "Null", "Value" : null } }
以下指令可以列出 Instance 中所有 DICOM 標籤編號:
# 列出所有 DICOM 標籤編號
curl http://localhost:8042/instances/03c9a57e-19836571-d4eefc16-2ad94243-9c8b63e2/content
[ "0008-0005", "0008-0008", "0008-0012", [略] "7fe0-0010" ]
依據 DICOM 標籤的編號,可直接提取標籤內的原始內容:
# 顯示指定 DICOM 標籤內容
curl http://localhost:8042/instances/03c9a57e-19836571-d4eefc16-2ad94243-9c8b63e2/content/0010-0010
Anonymized
亦可提取 sequence 中的 DICOM 標籤內容:
# 顯示指定 DICOM 標籤內容
curl http://localhost:8042/instances/03c9a57e-19836571-d4eefc16-2ad94243-9c8b63e2/content/0040-0275/0/0040-0008/0/0008-0102
XPLORE
若要下載指定 Instance 的 DICOM 檔案,可以執行:
# 下載指定 Instance 的 DICOM 檔案 curl http://localhost:8042/instances/03c9a57e-19836571-d4eefc16-2ad94243-9c8b63e2/file > output.dcm
若要預覽用的 PNG 圖片檔,可以執行:
# 下載指定 Instance 預覽用 PNG 圖片檔 curl http://localhost:8042/instances/03c9a57e-19836571-d4eefc16-2ad94243-9c8b63e2/preview > preview.png
若要下載 JPEG 格式的預覽用圖片檔,可以在 HTTP 的標頭加上 Accept: image/jpeg
:
# 下載指定 Instance 預覽用 JPEG 圖片檔 curl -H 'Accept: image/jpeg' http://localhost:8042/instances/03c9a57e-19836571-d4eefc16-2ad94243-9c8b63e2/preview > preview.jpg
若要一次下載包含整個 Study 中所有 Instances 的壓縮檔,可以執行:
# 下載包含整個 Study 中所有 Instances 的壓縮檔 curl http://localhost:8042/studies/3abaec0a-ebfaaa87-f830d52b-d62df074-6a692c12/archive > study.zip
以下指令可用於刪除 Patient、Study、Series 與 Instance:
# 刪除指定 Instance curl -X DELETE http://localhost:8042/instances/a1adcd88-1b3d3d3b-17938393-cfa13eb7-73e3a5f1
{ "RemainingAncestor" : { "ID" : "98d367a5-58eeba8b-f3c2da4b-de7d8f6f-ede53eb2", "Path" : "/series/98d367a5-58eeba8b-f3c2da4b-de7d8f6f-ede53eb2", "Type" : "Series" } }
# 刪除指定 Series curl -X DELETE http://localhost:8042/series/98d367a5-58eeba8b-f3c2da4b-de7d8f6f-ede53eb2
{ "RemainingAncestor" : null }
# 刪除指定 Study curl -X DELETE http://localhost:8042/studies/3abaec0a-ebfaaa87-f830d52b-d62df074-6a692c12 # 刪除指定 Patient curl -X DELETE http://localhost:8042/patients/b6589fc6-ab0dc82c-f12099d1-c2d40ab9-94e8410c
若要查詢 Orthanc 伺服器內的 DICOM 資料異動記錄,可以執行:
# 查詢 Orthanc 伺服器內 DICOM 資料異動記錄
curl http://localhost:8042/changes
{ "Changes" : [ { "ChangeType" : "NewInstance", "Date" : "20220313T120951", "ID" : "03c9a57e-19836571-d4eefc16-2ad94243-9c8b63e2", "Path" : "/instances/03c9a57e-19836571-d4eefc16-2ad94243-9c8b63e2", "ResourceType" : "Instance", "Seq" : 493 }, { "ChangeType" : "NewSeries", "Date" : "20220313T120951", "ID" : "98d367a5-58eeba8b-f3c2da4b-de7d8f6f-ede53eb2", "Path" : "/series/98d367a5-58eeba8b-f3c2da4b-de7d8f6f-ede53eb2", "ResourceType" : "Series", "Seq" : 494 }, [略] ], "Done" : false, "Last" : 592 }
Orthanc 會根據 DICOM 的 PatientID
、StudyInstanceUID
、SeriesInstanceUID
與 SOPInstanceUID
來產生 Orthanc 內部用的識別碼,而 /tools/lookup
這個 Restful API 可以藉由 PatientID
、StudyInstanceUID
、SeriesInstanceUID
或 SOPInstanceUID
查詢對應的 Orthanc 識別碼:
# 透過 PatientID、StudyInstanceUID、SeriesInstanceUID 或 SOPInstanceUID 查詢 Orthanc 識別碼 curl -X POST http://localhost:8042/tools/lookup -d 1.2.826.0.1.3680043.8.1055.1.20111102150934559.65578712.31022014
[ { "ID" : "fd410868-fab5df0e-808877ef-81bd239d-d442f2db", "Path" : "/instances/fd410868-fab5df0e-808877ef-81bd239d-d442f2db", "Type" : "Instance" } ]
通常我們不會讓 Orthanc 伺服器直接對外服務,而會採用反向代理(reverse proxy)的方式,透過 Nginx 這類標準的網頁伺服器讓外部連線。以下是在 Nginx 設定檔案中,加入 Orthanc 伺服器用的反向代理範例。
server { # ... # Orthanc 伺服器 location /orthanc/ { auth_basic "Orthanc"; auth_basic_user_file /etc/nginx/health.htpasswd; include proxy_params; proxy_pass http://localhost:8042/; } }
這裡我們也加入了 HTTP 基本認證(basic access authentication),讓使用者需要帳號與密碼才能連進 Orthanc 伺服器,而 /etc/nginx/health.htpasswd
這個帳號與密碼的設定檔可以使用 apache2-utils
套件中的 htpasswd
指令工具來產生:
# 安裝 apache2-utils 套件 sudo apt-get install apache2-utils # 建立帳號與密碼設定檔 sudo htpasswd -c /etc/nginx/health.htpasswd myuser # 新增其他帳號 sudo htpasswd /etc/nginx/health.htpasswd myuser2
若不想使用 htpasswd
指令工具,也可以改用 openssl
指令產生帳號與密碼設定檔:
# 建立帳號與密碼設定檔 sudo sh -c "echo -n 'myuser:' >> /etc/nginx/health.htpasswd" sudo sh -c "openssl passwd -apr1 >> /etc/nginx/health.htpasswd"
更改完 Nginx 伺服器的設定之後,重新啟動 Nginx 服務讓設定值生效:
# 重新啟動 Nginx 網頁伺服器服務
sudo systemctl restart nginx
安裝 PostgreSQL 資料庫與 Orthanc 的 PostgreSQL 套件:
# 安裝 PostgreSQL 資料庫與 Orthanc 的 PostgreSQL 套件
sudo apt install postgresql orthanc-postgresql
新增 Orthanc 專用的 PostgreSQL 資料庫使用者 orthanc
:
# 新增 PostgreSQL 使用者 orthanc sudo -u postgres createuser -e -P orthanc
Enter password for new role: Enter it again: SELECT pg_catalog.set_config('search_path', '', false); CREATE ROLE orthanc PASSWORD 'md5ed2e7015e36e2c35a07d922b5b5053ac' NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN;
新增一個 orthanc_db
資料庫,並將資料庫的擁有者設定為 orthanc
:
# 新增 orthanc_db 資料庫(擁有者為 orthanc) sudo -u postgres createdb -e -E utf8 -O orthanc orthanc_db
SELECT pg_catalog.set_config('search_path', '', false); CREATE DATABASE orthanc_db OWNER orthanc ENCODING 'utf8';
編輯 /etc/orthanc/postgresql.json
設定檔,將原本設定改為以下設定:
{ "PostgreSQL" : { // 以 PostgreSQL 儲存索引 "EnableIndex" : true, // 以 PostgreSQL 儲存影像 "EnableStorage" : false, // Option 1: Specify explicit authentication parameters "Host" : "localhost", "Port" : 5432, "Database" : "orthanc_db", "Username" : "orthanc", "Password" : "YOUR_PASSWORD", // 停用 PostgreSQL 資料庫鎖定(選用) "Lock" : false } }
修改好 Orthanc 的 PostgreSQL 設定之後,重新啟動 Orthanc 服務:
# 重新啟動 Orthanc 服務
sudo systemctl restart orthanc
透過 Ubuntu 官方套件庫所安裝的 Orthanc 伺服器版本會比較舊,若需要新版本的 Orthanc,可以參考 Orthanc 的文件,自行替換為 LSB(Linux Standard Base)版:
# 停止 Orthanc 服務 sudo service orthanc stop # 下載 Orthanc 執行檔 sudo wget https://lsb.orthanc-server.com/orthanc/1.11.1/Orthanc --output-document /usr/sbin/Orthanc # 刪除 Orthanc 外掛模組 sudo rm -f /usr/share/orthanc/plugins/*.so # 下載 Orthanc 外掛模組 cd /usr/share/orthanc/plugins/ sudo wget https://lsb.orthanc-server.com/orthanc/1.11.1/libServeFolders.so sudo wget https://lsb.orthanc-server.com/orthanc/1.11.1/libModalityWorklists.so sudo wget https://lsb.orthanc-server.com/orthanc/1.11.1/libConnectivityChecks.so sudo wget https://lsb.orthanc-server.com/orthanc/1.11.1/libDelayedDeletion.so sudo wget https://lsb.orthanc-server.com/orthanc/1.11.1/libHousekeeper.so sudo wget https://lsb.orthanc-server.com/plugin-dicom-web/1.7/libOrthancDicomWeb.so sudo wget https://lsb.orthanc-server.com/plugin-postgresql/4.0/libOrthancPostgreSQLIndex.so sudo wget https://lsb.orthanc-server.com/plugin-postgresql/4.0/libOrthancPostgreSQLStorage.so sudo wget https://lsb.orthanc-server.com/stone-webviewer/2.3/libStoneWebViewer.so sudo wget https://lsb.orthanc-server.com/plugin-webviewer/2.8/libOrthancWebViewer.so # 啟動 Orthanc 服務 sudo service orthanc start