マイブログ リスト

医療言語処理講座

2019年7月7日日曜日

Pyゼミ1.05 DICOM JPEG圧縮画像を解凍する

外部コマンドを使ってDICOM圧縮画像を解凍する


Keyword: DICOM JPEG圧縮、解凍、外部コマンド、DCMTK


先日、妻が半月板損傷の手術で入院しました。
術後撮影したMRI画像をCDで病院からいただき、講義・実習用に使おうと考えていました。

ところがDICOM画像はJPEG圧縮されていました。
そこで今回は画像を解凍するプログラムを紹介します。
注目する機能は次の2つを紹介します。

  • DICOM JPEG圧縮画像を解凍するDCMTKの紹介
  • DCMTKの解凍コマンドをpythonのプログラム内から呼び出す方法


DICOM Tool Kit


DICOM Tool kitは圧縮・解凍だけなく様々な機能がコマンドとして提供されています。
詳細な情報はここに書かれています。

特徴としてはWindows、LinuxやMacOSで利用可能です。
もちろんここではUbuntuで利用することを前提にします。

DCMTKのインストール


1行で簡単にインストールすることができます。

$ sudo apt install dcmtk



DICOM JPEG画像解凍コマンド dcmpjpeg


解凍にdcmpjpegを使います。
DCMTKをインストール後にコマンドを打ち込んでみましょう

下記のように使い方とオプションが表示されます。

$ dcmdjpeg
$dcmtk: dcmdjpeg v3.6.2 2017-07-14 $

dcmdjpeg: Decode JPEG-compressed DICOM file
usage: dcmdjpeg [options] dcmfile-in dcmfile-out

parameters:
  dcmfile-in                     DICOM input filename to be converted
  dcmfile-out                    DICOM output filename
(続く)

オプションの内容については割愛しましたが、ここでは”-u”を使います。

意味は” disable support for new VRs, convert to OB”とあり、
「新しいVR(Value Representation、値表現)のサポートを無効にし、OB(Other Byte String 8bit)に変換する」
となります。。

対象とするDICOM画像により微妙にオプションを調整あるいは付けない選択をする必要があります。

テスト画像の準備


JPEG圧縮した画像のサンプルがJIRA(日本画像医療システム工業会)のホームページにDICOM画像ファイルがあります。

解凍テストのために、MR_JPG_IR6a.dcmとMR_JPG_IR87a.dcmをダウンロードします。

画像ファイルをcompDicomというディレクトリを作成しその中に保存します。

解凍後の画像を保存するディレクトリdecompを作成しておきます。

準備完了です。


プログラム


プログラムはmain関数の中ではじめに圧縮画像が保存されたディレクトリと解凍した画像を保存するディレクトリをそれぞれ変数dcmdirとdstdirにそれぞれに代入します。

dcmdirディレクトリに保存されている画像の一覧をlistdirメソッドを使って配列(リスト)flistに代入します。

次にfor文を使ってflistに入っている画像を1画像づつfnameに代入して、decompjpeg関数を使って解凍処理を行います。

解凍舌画像をpydicomを使って読み込み、患者氏名などの基本情報をprintします。

decompjpeg関数は圧縮された画像ファイル名fname_iと解凍後のファイル名fname_oを引数に持ちます。

はじめに、解凍するためのdcmtkのコマンド”dcmjpeg”とオプションの"-u"をそれぞれ変数cmdとoptに代入します。

実行するコマンドラインを変数cmdlineに作成します。
このcmdlineをsubprocessライブラリのcheck_callメソッドに渡します。
このメソッドはcmdlineの実行がうまく行った場合、0を返します。

以上がプログラムの説明です。



dcmdecomp.py

  1. import os, sys
  2. import subprocess
  3. import pydicom  # pydicom 1.0
  4.  
  5. def decompjpeg(fname_i, fname_o):       # DCMTKを用いて圧縮画像を解凍する
  6.     cmd = "dcmdjpeg"        # DCMTKのコマンド
  7.     opt = "-u"              # オプション
  8.  
  9.     cmdline = cmd + " " + opt + " " + fname_i + " " + fname_o
  10.  
  11.     #外部プログラム dcmd -f  を起動
  12.     proc = subprocess.check_call( cmdline, shell=True)
  13.  
  14.     if proc == 0:
  15.         print("解凍成功:", proc, fname_o)
  16.     else:
  17.         print("\n\n解凍失敗:", proc, fname_o)
  18.  
  19.     return proc
  20.  
  21.  
  22. if __name__=='__main__': 
  23.     dcmdir = "./compDicom/"
  24.     dstdir = "./decomp/"   # Distnation directory
  25.     print("compressed Dicom image dir    = ", dcmdir)
  26.     print("decompressed image dir = ", dstdir)
  27.      
  28.     flist = os.listdir(dcmdir)  #DICOM元画像のファイルリスト作成
  29.  
  30.     for fname in flist:
  31.         decompjpeg( dcmdir + fname, dstdir + fname )     #画像解凍処理
  32.              
  33.         ds = pydicom.read_file(dstdir + fname)
  34.         print("\nPatinet ID         : ", ds.PatientID)
  35.         print("Study Date         : ", ds.StudyDate)
  36.         print("Study Instance UID : ", ds.StudyInstanceUID)
  37.         print("SOP instance UID   : ", ds.SOPInstanceUID)


プログラムを実行してみましょう。



$ python dcmdecomp.py
compressed Dicom image dir    =  ./compDicom/
decompressed image dir =  ./decomp/

解凍成功: 0 ./decomp/MR_JPG_IR6a.dcm
Patinet ID         :  999999-004
Study Date         :  20041012
Study Instance UID :  1.2.392.200036.8120.100.20041012.1123100.2001
SOP instance UID   :  1.2.392.200036.8120.100.20041012.1123100.2001002010

解凍成功: 0 ./decomp/MR_JPG_IR87a.dcm
Patinet ID         :  999999-004
Study Date         :  20041012
Study Instance UID :  1.2.392.200036.8120.100.20041012.1123100.2001
SOP instance UID   :  1.2.392.200036.8120.100.20041012.1123100.2001002010


実行後、decompディレクトリに解凍画像が保存されています。
compDicomディレクトリにある画像は129kbですが、compディレクトリには206kbになり容量が増えています。


おわりに


DICOM JPEG圧縮画像を解凍するdcmdjepgコマンドを紹介しました。
DICOM Tool Kitは簡単にインストールできるのでとても便利です。

また、外部コマンドをpythonから起動する方法を紹介しました。
コンソールからコマンドを打ち込むように記述すればよく、他の外部コマンドにも応用可能です。