はじめに
最近、DICOMのファイルを機械学習する必要があって色々調べていたらPythonでは簡単に読み込むライブラリがあるとのことでした。
Pillowを使うと画面に表示ができるのですが、そこから少し加工しようと思ってOpenCVに入れるとなんかおかしい...
これは、そんなライブラリでやりたいことができるようになるまでの物語である。
使用環境
- Python 3.10.x
- pydicom 2.4.4
- Pillow(PIL) 9.0.1
- OpenCV(cv2) 4.10.0
使用データ
日本放射線技術学会画像部会のデータを使用します。
一般的なやり方
ネットで検索すると以下の方法が紹介されていました。
import pydicom
from matplotlib import pyplot as plt
ds = pydicom.read_file("JPCLN0xx.dcm")
img = ds.pixel_array
plt.imshow(img, cmap='gray')
plt.show()
できた。
これを画像データとして使用するには、以下の手順でファイルに保存して再読み込みします。
plt.imsave('JPCLN0xx.jpg', img, cmap='gray')
できたけど、なんだかちょっと嫌な気がする。
OpenCVで使えるようにしてみる
とりあえず読み込む
画像データをOpenCVに読み込ませて表示させてみる
import cv2
from PIL import Image as im
from IPython.display import display, Image
_, buf = cv2.imencode(".jpg", img)
dat = Image(data=buf.tobytes())
display(dat)
...真っ白。
少しデータを見てみる
パラメータの最大値を確認
mx = 0.0
for x in range(img.shape[0]):
for y in range(img.shape[1]):
if mx < img[x, y]:
mx = img[x, y]
print(mx)
出力結果は
4095
これが原因っぽい。
考察
通常パソコンで使用される色の階調は0〜255だけど、DICOMでは0〜4095となっているみたい。
なので、4096階調を256階調に変換してやればいいのかもしれない。
データを加工してみる
imgの全ての値を4096で割って256をかけてみます。
img2 = img / (mx + 1) * 256.0
import cv2
from PIL import Image as im
from IPython.display import display, Image
_, buf = cv2.imencode(".jpg", img2)
dat = Image(data=buf.tobytes())
display(dat)
できた!
この画像を使ってアノテーション作業を行なって、実際の処理は元の4096階調を使うようにして機械学習させればいいかも!
別にmatplotlibでもできるけどね、これまで作ってきたスクリプトがOpenCVを使っているのでそれと同じようにできれば楽かな〜って感じでした。