はじめに
いままでの記事でファイル選択を幾度となく扱ってきましたが、フォルダを選択することでファイルを一括選択する際になぜか、画像の並び順がおかしいと気が付き調べてみました。
ファイルを複数選択した場合
ファイルを複数選択する方法を調べてみました。
「画像選択のプログラムを使いやすく!!」で作成したファイルを複数選択する方法で試してみました。
方法としてはファイルを複数選択し、for文を用いて一つ一つファイルパスを表示する原始的な方法です。
# -*- coding: utf-8 -*-
import fileselect as fs
import pydicom
####ファイルを複数選択する方法########
filenames = fs.multi_fileselect()
for i in range(len(filenames)):
print(filenames[i])
結果です。
ファイルは、順番通りに読み込まれています。
ファイルをフォルダで一括選択する方法
# -*- coding: utf-8 -*-
import fileselect as fs
import pydicom
####ファイルをフォルダで選択する方法###
filenames = fs.folder_fileselect()
for i in range(len(filenames)):
print(filenames[i])
結果です。
読み込まれている順番がファイルの数字順ではなく読み込まれていることが確認できます。ファイル名の数字を文字列として扱っているという事だと思います。(面倒で調べていません。。。)
対処法を考えた。
それでは、どうすればフォルダで一括選択した時にスライス順に取り込んでいく事ができるか、image-Jで先ほどのDICOMタグを見てみました。
画像情報に関する情報はDICOM Blockでは0020に登録されていますので見てみます。
0020,0013にImageNumberというものがあります。(正式にはInstance Number)これが画像番号となりますのでこれの通りに読み込めばいいことになります。
実際にコードを書いていく。
まずはフォルダで一括ファイル選択をし、ファイル数だけの要素を持つリストを作成します。
空のリストを作成するには以下のコードで作れます。
filename_list =[] #リストを作成
for i in range(len(filenames)): #ファイル数だけ要素を追加
filename_list.append('')
numpyの場合、簡単に配列を作成できますが今回はリストなのでfor文で繰り返し、空の要素をファイル数だけ追加していきます。(上記コード3~4行目)
その後、filenamesを一つづつ読み込みDICOMタグを読み込みImageNumber-1の場所(リストは番号0から始まりますが、ファイル番号は1から始まりますので‐1しています。)に書き込みをしていきます。
その後、ファイルパスを表示していくコード(下のコード7~8行目)を書いて確認してみましょう。
for i in range(len(filenames)):
dcm = pydicom.dcmread(filenames[i])
img_no = int(dcm[0x0020,0x0013].value)
filename_list[img_no-1] = filenames[i]
for i in range(len(filenames)):
print(filename_list[i])
結果です。
無事にファイル番号順に読み込むことができました。
試したコードは以下となります。
# -*- coding: utf-8 -*-
import fileselect as fs
import pydicom
filenames = fs.folder_fileselect()
filename_list =[]
for i in range(len(filenames)):
filename_list.append('')
for i in range(len(filenames)):
dcm = pydicom.dcmread(filenames[i])
img_no = int(dcm[0x0020,0x0013].value)
filename_list[img_no-1] = filenames[i]
for i in range(len(filenames)):
print(filename_list[i])
最後に
今回、ファイルパスにて確認作業を行いましたが、実際画像処理をしていくときにはファイルパスはあまり必要としません。
必要になってくるのはピクセルデータなのでフォルダ選択が完了した段階で
0で埋めた配列を作成し、ImageNumber-1にピクセルデータを入れることで対処することができます。
例としては以下となります。
# -*- coding: utf-8 -*-
import fileselect as fs
import pydicom
import numpy as np
filenames = fs.folder_fileselect()
pix_arr = np.zeros((len(filenames), row, columns),dtype = 'int16')
for i in range(len(filenames)):
dcm = pydicom.dcmread(filenames[i]
img_no = int(dcm[0x0020,0x0013].value)
pix_arr[img_no-1] = dcm.pixel_array
いかがでしたか?
もし、フォルダでファイルを一括選択を使用される場合は参考にしていただければ幸いです。
お疲れ様でした。
環境
- windows10
- python3.6.1
- Anaconda custom(64-bit)
- PyCharm2020.2(Communication Edition)