免費工具

Orthanc DICOM 影像伺服器安裝與使用教學

介紹如何在 Ubuntu Linux 中安裝與設定 Orthanc DICOM 影像伺服器,並以 Restful API 來操控 PACS 系統。

安裝 Orthanc

若在 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 影像的各種功能。

Orthanc 網頁介面

管理者可以使用 systemctl 來查看或控制系統上的 orthanc 服務:

# 查看 orthanc 服務狀態
systemctl status orthanc

# 啟動 orthanc 服務
sudo systemctl start orthanc

# 重新啟動 orthanc 服務
sudo systemctl restart orthanc

# 停止 orthanc 服務
sudo systemctl stop orthanc

匯入 DICOM 影像

這裡我們採用 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 檔案。

查詢 DICOM 資訊

若要查詢 Orthanc 伺服器中的 DICOM 資訊,也可以透過 Restful API 來執行,查詢的結果都會以 JSON 格式呈現。

列出所有 DICOM 資源

以下是使用 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 的資訊,可以執行:

# 查詢 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 的資訊,可以執行:

# 查詢 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 的資訊,可以執行:

# 查詢 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 的資訊,可以執行:

# 查詢 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"
}

查看 DICOM 標籤

若要查看指定 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

下載 DICOM 檔案

若要下載指定 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

若要一次下載包含整個 Study 中所有 Instances 的壓縮檔,可以執行:

# 下載包含整個 Study 中所有 Instances 的壓縮檔
curl http://localhost:8042/studies/3abaec0a-ebfaaa87-f830d52b-d62df074-6a692c12/archive > study.zip

刪除 DICOM 資料

以下指令可用於刪除 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 識別碼

Orthanc 會根據 DICOM 的 PatientIDStudyInstanceUIDSeriesInstanceUIDSOPInstanceUID 來產生 Orthanc 內部用的識別碼,而 /tools/lookup 這個 Restful API 可以藉由 PatientIDStudyInstanceUIDSeriesInstanceUIDSOPInstanceUID 查詢對應的 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"
   }
]

整合 Nginx 伺服器

通常我們不會讓 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 資料庫

安裝 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

更換新版 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

參考資料

Share
Published by
Office Guide
Tags: DICOM

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

1 年 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

1 年 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

1 年 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

1 年 ago