【初心者向け】基礎&実践プログラミング

初心者がつまづきやすいところ、最短で実力が身につく方法をお伝えします。

【Python】DICOMからPNGやCSVに変換

f:id:AIProgrammer:20200501170605p:plain

はじめに

AIを作成するために、MRI画像をDICOM形式からPNG形式あるいはCSV形式に変換する必要があった。 件数は1700件ほど。 有名なものとしてはDICOM Cenverterがあるが、大量のDICOMをInputすると固まってしまう。 (199.99$で買わなきゃいけないのか??) そこで、pythonを使ってDICOMからPNG形式あるいはCSV形式に変換するコードを作成した。

前準備

DICOMの読み取りに必要なpydicomとPNGとして保存する上でひつようなopencv-pythonを用意する。

$ pip3 install pydicom
$ pip3 install opencv-python

準備

1つのフォルダの中に変換したいDICOMを用意する。

$ ls
instance_1.dcm   instance_14.dcm  instance_19.dcm  instance_6.dcm
instance_10.dcm  instance_15.dcm  instance_2.dcm   instance_7.dcm
instance_11.dcm  instance_16.dcm  instance_3.dcm   instance_8.dcm
instance_12.dcm  instance_17.dcm  instance_4.dcm   instance_9.dcm
instance_13.dcm  instance_18.dcm  instance_5.dcm

実行

以下のコードを実行する。

import numpy as np
import pydicom  
import glob
import cv2

def dcm2png_csv(dcm):
    d = pydicom.read_file(dcm)
    value = d.pixel_array
    wc = d.WindowCenter
    ww = d.WindowWidth
    max, min = wc + ww / 2, wc - ww / 2
    value_std = 255 * (value - min) / (max - min)
    cv2.imwrite((dcm[:-4]+'.png'), value_std)
    np.savetxt((dcm[:-4]+'.csv'),value,delimiter=',')

for dcm in glob.glob('*dcm'):
    dcm2png_csv(dcm)

必要なmoduleのimport

import numpy as np
import pydicom  
import glob
import cv2

DICOMの読み込み

DICOMのヘッダーから値まで読み込める。 "d.pixel_array"画像の画素値にあたる。 (大人の事情でヘッダー等はみせられません(泣))

d = pydicom.read_file(dcm)
value = d.pixel_array

コントラストの調節

値を読み込んでそのままPNGに保存してはコントラストがおかしな画像がでてくる。 MRI画像は16 bitでデータを収集されているのに対し、PNGは8 bitであるためおかしくなる。 DICOMのタグの中でコントラストを決定するWindow Center(WC)とWindow Width(WW)を取得し、それが8 bitの状態で正しく見えるように正規化する。

wc = d.WindowCenter
ww = d.WindowWidth
max, min = wc + ww / 2, wc - ww / 2
value_std = 255 * (value - min) / (max - min)

ここのサイトの画像がわかりやすいです。この例では、12 bitのデータを8 bitに変換しています。 image.png

PNGおよびCSVの保存

PNGとCSVの保存をします。 PNGは8 bitですので正規化され"value_std"をPNGにします。 ですが、16 bitが8 bitですから情報としては少なくなってしまうわけです。 これがAIの判定精度に影響を与える場合があります。 ですので、生の値をCSVに保存することも重要です。 ということで、CSVにするのは"value"。

### PNG保存
cv2.imwrite((dcm[:-4]+'.png'), value_std)
### CSV保存
np.savetxt((dcm[:-4]+'.csv'),value,delimiter=',')

結果

わかりずらいですが、PNGが増えたことがわかります。

$ ls
instance_1.dcm   instance_14.dcm  instance_19.dcm  instance_6.dcm
instance_1.png   instance_14.png  instance_19.png  instance_6.png
instance_10.dcm  instance_15.dcm  instance_2.dcm   instance_7.dcm
instance_10.png  instance_15.png  instance_2.png   instance_7.png
instance_11.dcm  instance_16.dcm  instance_3.dcm   instance_8.dcm
instance_11.png  instance_16.png  instance_3.png   instance_8.png
instance_12.dcm  instance_17.dcm  instance_4.dcm   instance_9.dcm
instance_12.png  instance_17.png  instance_4.png   instance_9.png
instance_13.dcm  instance_18.dcm  instance_5.dcm
instance_13.png  instance_18.png  instance_5.png

まとめ

DICOMからPNGやCSVに無料変換するコードを作成した。 このコードをforで回せば一括変換できるので便利かと!



頑張れ!喝!!の代わりにB!ブックマークを押していただけるとただただうれしいです(^^)! ↓