dicom ファイルを jpg に変換する python

新しい内視鏡システム UNITEA は、pacs に接続して dicom ファイルを生成するのですが、これまでのシステムでは jpg ファイルとそれを管理するデータベースでそれなりに快適に動作しており、どちらかに統一する必要があると思っていました。

これまでは、jpg ファイルを dicom ファイルに変換して pacs にインポートすることを考えていましたが、そうするとファイルの容量が巨大になります。

そこで、dicom ファイルを jpg に変換して、dicom ファイルのタグ情報をこれまでのデータベースに記録することにしました。

pacs には dicom ファイルがどんどん蓄積されるのですが、メインで内視鏡画像を閲覧するのは、これまで通り php で jpg ファイルを閲覧します。
内視鏡は dicom じゃなくて jpg でも十分だと思います。

dicom の内視鏡画像を jpg ファイルに変換


import pydicom
from PIL import Image

file = pydicom.dcmread('/var/www/html/demo/sample.dcm')
img = file.pixel_array
pil_img = Image.fromarray(img)
pil_img.save('/var/www/html/demo_jpg/sample.jpg')

結果は、

以前、色調がおかしくなった Plissimo EX の dicom ファイルも、

きちんと変換されました。

CT画像を jpg に変換

CT画像を同じように変換しようとすると、以下のようなエラーが出ます。


OSError: cannot write mode I as JPEG

ネット上にあるいろいろなコードを試してみましたが、きちんと変換できませんでした。

そしてさらにいろいろと検索して dicom2jpg に到達、これ最高です。

今のところ情報が少なすぎて詳細は不明ですが、以下のようにして使用するようです。

まずは、dicom2jpg をインストール。


pip install dicom2jpg

python は、


import dicom2jpg

dicom_dir = "/var/www/html/demo"
export_location = "/var/www/html/demo_jpg"

dicom2jpg.dicom2jpg(dicom_dir, target_root=export_location) 

これはディレクトリごと jpg に変更する場合です。
だだし、ファイルの拡張子が「.dcm」でなければなりません。

jpg 変換された画像は、

画像としてはこれでいいと思います。

詳細なオプションに関して調べる必要があります。

画像書き出しに関する設定

インストールされた dicom2jpg の utils.py に保存方法の細かい設定がしてあります。

dicom を jpg に変換した後で保存するのは、


full_export_fp_fn = target_root/Path(today_str)/Path(f"{PatientID}_{filetype}")/Path(f"{StudyDate}_{StudyTime}_{Modality}_{AccessionNumber}")/Path(f"{SeriesNumber}_{InstanceNumber}.{filetype}")

とされています。
ここを変更するのは少し気が重いです。

作成されたディレクトリを見ると以下のようになっています。


.
└── 20220930
    ├── 21900283_jpg
    │   └── 20190204_102011_CT_
    │       ├── 3_1.jpg
    │       ├── 3_2.jpg
    │       ├── 3_3.jpg
    │       ├── 3_4.jpg
    │       ├── 3_5.jpg
    │       ├── 3_6.jpg
    │       ├── 3_7.jpg
    │       ├── 3_8.jpg
    │       └── 3_9.jpg
    └── ES07_jpg
        └── 20190827_085053_ES_
            └── 1_42.jpg

なるほどこれはこれでいいでしょうか。

python でシェルスクリプトを実行して画像処理

dicom ファイルを1ヶ所に集めて dicom2jpg を実行すれば、dicom ファイルのタグ情報によって python が自動的に処理してくれます。

しかし、dicom2jpg で処理する場合、ファイルの拡張子は「.dcm」でなければなりません。

dcm4chee はどういうわけか dicom ファイルの拡張子を付けません。
なのでそのままでは dicom2jpg が認識しれくれません。

そこで以前作ったシェルスクリプトで拡張子なしの dicom ファイルを処理することにしました。

dcmlist.sh

#!/bin/bash

origin="/home/user/tmp"
destination="/home/user/tmp/dcms/"

for fl in `\find $origin -maxdepth 6 -type f`; do
    a=`file -b $fl`
    if [[ $a = "DICOM medical imaging data" ]];then
        fn=`basename $fl`
        echo $fn
        mv $fl $destination$fn".dcm"
    fi
done

このシェルスクリプトを python から実行し、集められた .dcm ファイルを処理します。


import subprocess
import dicom2jpg

cmd = ("/home/user/dcmlist.sh")
process = (subprocess.Popen(cmd, stdout=subprocess.PIPE,
                           shell=True).communicate()[0]).decode('utf-8')

dicom_dir = "/home/user/tmp/dcms"
export_location = "/var/www/html/demo_jpg"

dicom2jpg.dicom2jpg(dicom_dir, target_root=export_location) 

やっぱり utils.py を変更する

dcm4chee で保存されている dicom ファイルにも、UNITEA で作成される dicom ファイルにも AccessionNumber は設定されていません。ブランクです。

であれば、AccessionNumber は要らないということになります。

また、_jpg も要らない。

つまり、「本日の日付」/「カルテ番号」/「検査日_検査時刻_モダリティ」で十分にユニークだからです。

utils.py を以下のように書き換えました。


full_export_fp_fn = target_root/Path(today_str)/Path(f"{PatientID}")/Path(f"{StudyDate}_{StudyTime}_{Modality}")/Path(f"{SeriesNumber}_{InstanceNumber}.{filetype}")

そうすると、出来上がるファイル構造は、


.
└── 20220930
    ├── 21900283
    │   └── 20190204_102011_CT
    │       ├── 3_1.jpg
    │       ├── 3_2.jpg
    │       ├── 3_3.jpg
    │       ├── 3_4.jpg
    │       ├── 3_5.jpg
    │       ├── 3_6.jpg
    │       ├── 3_7.jpg
    │       ├── 3_8.jpg
    │       └── 3_9.jpg
    └── ES07
        └── 20190827_085053_ES
            └── 1_42.jpg

この情報を含めて、必要な情報をデータベースに書き込めば、これまでの内視鏡データベースの上に画像データを積み上げることができます。