MRI画像をスライダーを使ってウインドウ調整(OpenCV編)修正版(配列の型)

OpenCV

前回、前々回で「MRI画像をスライダーを使ってウインドウ調整」ということで記事を書かせていただきましたが、記載後いくつか修正したい部分が出てきましたのでそこを今回と次回で直していきたいと思います。今回は配列の型の指定を修正したいと思います。

前回のコード


import fileselect as fs   #ファイルパス取得のモジュールをインポート
import numpy np
import pydicom
import math
import copy

filenames = fs.multi_fileselect

dcm = pydicom.dcmread(filenames[0])
row,columns = dcm.pixel_array.shape[0],dcm.pixel_array.shape[1]
       #読み込んだ画像の横方向を変数row、縦方向を変数columnsとして取得します。

dcm_copy = np.zeros((len(filenames), row, columns),dtype = int)
       #dcm_copyという名前で0で初期化した配列を作成

for i in range(len(filenames)):
    dcm = pydicom.dcmread(filenames[i])
    dcm_arr = dcm.pixel_array
    dcm_copy[i] = dcm_arr.astype(np.int64) 
      #np.int64としてデータの型を指定しておきます。

dcm_main = copy.deepcopy(dcm_copy)
      #深いコピーで複製します。

cv2.namedWindow('dcm_image',cv2.WINDOW_NORMAL)
      #ウインドウ名を'dcm_image'とし、ウインドウサイズを変更できるように設定

maxvalue = dcm_copy.max().astype(np.int64)
lookup_tbl = np.zeros(maxvalue+1, dtype=np.int64)
      #作成要素数を最大値+1としておく。

cv2.createTrackbar("WL", "dcm_image", (maxvalue // 2), maxvalue, make_LUT)
cv2.createTrackbar("WW", "dcm_image", (maxvalue // 4), maxvalue, make_LUT)

while 1:
    wl = cv2.getTrackbarPos('WL', 'dcm_image')
    ww = cv2.getTrackbarPos('WW', 'dcm_image')

    ww_low = wl - ww // 2
    ww_high = wl + ww // 2
    lookup_tbl[0:ww_low] = 0
    lookup_tbl[ww_high:maxvalue] = 255
    for i in range(ww_low, ww_high, 1):
        lookup_tbl[i] = math.ceil((i - ww_low) * (256 / (ww_high - ww_low)))

    dcm_copy = lookup_tbl[dcm_main]

    dcm_copy =cv2.convertScaleAbs(dcm_copy, alpha=255/dcm_copy.max())
    cv2.imshow('dcm_image', dcm_copy[0])

    k = cv2.waitKey(1)
    if k == ord('q'):
        break

def make_LUT(val):
    pass #何もしない

修正点 配列の型の指定

CTや、MRI画像は16ビット階調だということです。その為、DICOMヘッダー[0028,0100]に登録されているBits Allocatedの画像階調度も16と登録(自施設の装置では16)されていますので、それに合わせていきたい友ます。

まずは上記コードの14行目

dcm_copy = np.zeros((len(filenames), row, columns),dtype = int)

の 「dtype = int」を 「dtype = ‘int16’」と変更し以下となります。

dcm_copy = np.zeros((len(filenames), row, columns),dtype = ‘int16’)

続いて20行目は14行目で指定しているので「.astype(np.int64)」を削除して

dcm_copy[i] = dcm_arr

とスッキリさせてしまいましょう。

29~30行目は

maxvalueはdcm_copyの最大値を入れる変数であるので、元の配列の型を指定する必要もないので「.astype(np.int64)」を削除。

30行目の

lookup_tbl = np.zeros(maxvalue+1, dtype=np.int64)

は、「dtype=np.int64」を「dtype=’int16’」とし

lookup_tbl = np.zeros(maxvalue+1, dtype=’int16′)

以上で型の修正は終わりです。

最後に・・・・

上記コードはopenCVのimportを忘れていました。以下のコードで追加しておきます。また、関数のmake_LUTを上に持ってきました。

修正後のコードは以下となります。


import fileselect as fs   #ファイルパス取得のモジュールをインポート
import numpy as np
import pydicom
import math
import copy
import cv2

def make_LUT(val):
    pass #何もしない

filenames = fs.multi_fileselect

dcm = pydicom.dcmread(filenames[0])
row,columns = dcm.pixel_array.shape[0],dcm.pixel_array.shape[1]

dcm_copy = np.zeros((len(filenames), row, columns),dtype = 'int16')

for i in range(len(filenames)):
    dcm = pydicom.dcmread(filenames[i])
    dcm_arr = dcm.pixel_array
    dcm_copy[i] = dcm_arr

dcm_main = copy.deepcopy(dcm_copy)

cv2.namedWindow('dcm_image',cv2.WINDOW_NORMAL)

maxvalue = dcm_copy.max()
lookup_tbl = np.zeros(maxvalue+1, dtype='int16')

cv2.createTrackbar("WL", "dcm_image", (maxvalue // 2), maxvalue, make_LUT)
cv2.createTrackbar("WW", "dcm_image", (maxvalue // 4), maxvalue, make_LUT)

while 1:
    wl = cv2.getTrackbarPos('WL', 'dcm_image')
    ww = cv2.getTrackbarPos('WW', 'dcm_image')

    ww_low = wl - ww // 2
    ww_high = wl + ww // 2
    lookup_tbl[0:ww_low] = 0
    lookup_tbl[ww_high:maxvalue] = 255
    for i in range(ww_low, ww_high, 1):
        lookup_tbl[i] = math.ceil((i - ww_low) * (256 / (ww_high - ww_low)))

    dcm_copy = lookup_tbl[dcm_main]

    dcm_copy =cv2.convertScaleAbs(dcm_copy, alpha=255/dcm_copy.max())
    cv2.imshow('dcm_image', dcm_copy[0])

    k = cv2.waitKey(1)
    if k == ord('q'):
        break


次回はマウスホイールの機能を入れていきたいと思います。


環境

  • windows10
  • python3.6.1
  • Anaconda custom(64-bit)
  • PyCharm2020.2(Communication Edition)

コメント

タイトルとURLをコピーしました