質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Spyder

Spyderとは、Pythonで分析するために作られたIDEです。プログラムの編集・実行・入力補完・デバッグなどの基本的なIDE機能の他、科学用途の計算をするために要するライブラリも装備。公式・サードパーティ製のプラグインもあり、機能を拡張することもできます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

2650閲覧

出力画像をmhd形式で保存したいです。

1999sin

総合スコア1

Spyder

Spyderとは、Pythonで分析するために作られたIDEです。プログラムの編集・実行・入力補完・デバッグなどの基本的なIDE機能の他、科学用途の計算をするために要するライブラリも装備。公式・サードパーティ製のプラグインもあり、機能を拡張することもできます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2021/05/31 04:05

編集2021/05/31 04:32

前提・実現したいこと

プログラミング初心者です。
現在、spyderでコードを組んでおり、学習の入力画像はmhd形式、出力画像がnpy形式となっています。
出力画像をmhd形式に指定して保存するにはどのようにコードを書けばよいでしょうか。

発生している問題・エラーメッセージ

TypeError: Wrong number or type of arguments for overloaded function 'new_Image'. Possible C/C++ prototypes are: itk::simple::Image::Image() itk::simple::Image::Image(itk::simple::Image const &) itk::simple::Image::Image(unsigned int,unsigned int,itk::simple::PixelIDValueEnum) itk::simple::Image::Image(unsigned int,unsigned int,unsigned int,itk::simple::PixelIDValueEnum) itk::simple::Image::Image(std::vector< unsigned int,std::allocator< unsigned int > > const &,itk::simple::PixelIDValueEnum,unsigned int)

###使用言語
python

該当のソースコード

import os import glob import numpy as np import pandas as pd import SimpleITK as sitk import matplotlib.pyplot as plt from keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D, BatchNormalization from keras.layers.merge import concatenate from keras.models import Model from keras.callbacks import EarlyStopping #%% # パラメータ設定 EPOCHS = 10 BATCH_SIZE = 40 IMAGE_SIZE = 208 #%% # .mhd読み込み def load_itk(filename): itkimage = sitk.ReadImage(filename) raw_image = sitk.GetArrayFromImage(itkimage) return raw_image def load_images(inputpath, type_hospital,type_image): imglist = [] filenamelist = [] spacinglist = [] df_PETCT = pd.read_csv('dataset/PETCT_slice/df_top_z_point.csv') for path in glob.glob("{}\{}*\{}".format(inputpath, type_hospital,type_image)): for root, dirs, files in os.walk(path): name = os.path.split(os.path.split(root)[0])[1] top_lung = int(df_PETCT[(df_PETCT['name']==name)]['lung']) top_diap = int(df_PETCT[(df_PETCT['name']==name)]['diap']) for i in range(top_lung, top_diap): for filepath in glob.glob("{}*k={}.mhd".format(root, i)): filenamelist.append(os.path.splitext(os.path.split(filepath)[1])[0]) itkimage = sitk.ReadImage(filepath) raw_image = sitk.GetArrayFromImage(itkimage) raw_array = np.asarray(raw_image, dtype=np.float64) raw_array = raw_array.transpose(1, 2, 0) imglist.append(raw_array) raw_spacing = itkimage.GetSpacing() spacinglist.append(raw_spacing) imgdatas = np.asarray(imglist) return imgdatas, filenamelist, spacinglist def save_data(savepath, filenamelist, datalist): for i, fn in enumerate(filenamelist): filename = os.path.join(savepath, fn) testdata = np.asarray(datalist[i]) np.save(filename, testdata) def save_mhd_data(savepath, filenamelist, datalist, spacinglist): for i, fn in enumerate(filenamelist): filename = os.path.join(savepath, fn)+'.mhd' raw_array = datalist[i].transpose(2, 0, 1) tmp_itkimg = sitk.Image(raw_array) tmp_itkimg.SetSpacing(spacinglist[i]) sitk.WriteImage(tmp_itkimg, filename) save_data("dataset\result\", test_label_filenames, results) save_mhd_data("dataset\result\", test_label_filenames, results,spacinglist)

試したこと

def save_mhd_data(savepath, filenamelist, datalist, spacinglist):とコードを作成してみたのですが、mhdで保存されていませんでした。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

etherbeg

2021/05/31 17:15

こちらにDICOM画像をmhdに変換するコードがありますが、 https://github.com/hfarhidzadeh/DicomToMhd/blob/master/convert.py このコードではファイルに書き出す直前に置かれている sitk_img.SetOrigin(Origin) というコードが、質問者さんのコードにはありません。これが原因ということはあるでしょうか。 ところで質問文を読んでいくつか疑問があるのですが、 「発生している問題・エラーメッセージ」の箇所に記載されているエラーメッセージは、「出力画像をmhd形式で保存したい」という質問とどういう関係にあるのでしょうか。「試したこと」に記載されている「コードを作成してみたのですが、mhdで保存されていませんでした」という文章からは、保存はされていたけれどmhdファイルとしては不完全なファイルでmhdファイルとしては認識されなかった、といったようなニュアンスに感じられます(エラーが出て保存自体に失敗した、とは読めない。それともエラーは出たけどファイルは保存されていたということでしょうか)。 「mhdで保存されていなかった」とのことですが、そのことはどのように確認されたのでしょうか(言い換えると、何をもってmhdではないと判断したのか、もし保存されたファイルの状態を調べてそう判断したのなら、その内容を知りたい)。 「学習の入力画像はmhd形式、出力画像がnpy形式」とのことですが、入力画像と出力画像にはどのような違いがあるのでしょうか。「学習」という言葉とkerasをインポートしていることから、入力と出力の間で何か機械学習をしているのだろうと想像するのですが、画像データ自体にどういう変更や加工が施されているのかは質問文からは分かりません(つまり保存前の画像データの状態を知りたい)。 (上と関連する疑問ですが)save_data() もしくは save_mhd_data() に渡される直前の画像データはどのような状態になっているのでしょうか(データ型など)。load_images() 関数の結果が save_mhd_data() に渡されるデータかとも思ったのですが、それだと画像をload_images() 関数の中でmhdファイルから読み込んでいるように読めます。入力画像をmhdファイルから読み込んだらあとは機械学習を経て何らかの加工をしてmhdファイルとして保存、という流れかと思っていたので、途中でまたmhdファイルから読み込んでいるのは不可解に感じられます。
1999sin

2021/06/01 06:36

①「sitk_img.SetOrigin(Origin) というコードが、質問者さんのコードにはありません。これが原因ということはあるでしょうか。」 →試してみたのですが、以下のようなエラーが出ました。 IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices ②「「発生している問題・エラーメッセージ」の箇所に記載されているエラーメッセージは~」 →申し訳ございません、このエラーが直接関係しているのか定かではありません。とりあえず、実行したらこのエラーが出たといった感じです。 ③「mhdで保存されていなかった」とのことですが、そのことはどのように確認されたのでしょうか(言い換えると、何をもってmhdではないと判断したのか、もし保存されたファイルの状態を調べてそう判断したのなら、その内容を知りたい)。 →save_mhd_dataの最初の引数にセーブしたファイルのパスを入れているので、そのファイルの中身を確認し、.mhdのファイルが一つもなかったため、そう判断させて頂きました。 ④「学習の入力画像はmhd形式、出力画像がnpy形式」とのことですが、入力画像と出力画像にはどのような違いがあるのでしょうか。「学習」という言葉とkerasをインポートしていることから、入力と出力の間で何か機械学習をしているのだろうと想像するのですが、画像データ自体にどういう変更や加工が施されているのかは質問文からは分かりません(つまり保存前の画像データの状態を知りたい)。 →大変申し訳ございません。入力したmhdをnpy形式で出力し、保存しています。保存前の画像データは0-1の正規化処理を行ったものでfloat型となります。 ⑤(上と関連する疑問ですが)save_data() もしくは save_mhd_data() に渡される直前の画像データはどのような状態になっているのでしょうか(データ型など)。load_images() 関数の結果が save_mhd_data() に渡されるデータかとも思ったのですが、それだと画像をload_images() 関数の中でmhdファイルから読み込んでいるように読めます。入力画像をmhdファイルから読み込んだらあとは機械学習を経て何らかの加工をしてmhdファイルとして保存、という流れかと思っていたので、途中でまたmhdファイルから読み込んでいるのは不可解に感じられます。 →「入力画像をmhdファイルから読み込んだらあとは機械学習を経て何らかの加工をしてmhdファイルとして保存、という流れ」であっております。そもそも自分が作成したコードが間違えている可能性があります。申し訳ございません。
etherbeg

2021/06/01 12:55

詳しくお返事ありがとうございます。 申し訳ありませんが急遽、パソコンの前にゆっくり座っている時間がしばらくの間取れなくなってしまいました。 落ち着いたらまたゆっくり拝見させていただきます。
guest

回答1

0

ベストアンサー

回答が遅くなりました。

問題を単純化して、読み込んだmhd形式のファイルを、いったん画像データのみndarrayに変換してから、再度同じmhd形式で別名保存するとします。

質問文に添付された断片的なコードからは、正確にどのような過程を経て画像データの読み込みから書き出しまでが行われているかわからないのですが、推測を交えて以下のようにコードを拾って構成してみました(Pythonインタプリタで実行しています)。mhd形式のファイルは手元になかったので、ネットで探して
https://github.com/statgenetJimu/ShapeMove
のリポジトリにあったファイルを使わせていただきました。

Python

1>>> import numpy as np 2>>> import SimpleITK as sitk 3 4# mhd形式のファイルの読み込み 5>>> reader = sitk.ImageFileReader() 6>>> reader.SetImageIO("MetaImageIO") 7>>> reader.SetFileName("/Users/xxxx/ShapeMove-master/Data/seriesImage/out.mhd") 8>>> itkimage = reader.Execute() 9 10# 読み込んだ画像データをいったんndarrayに変換してから、再度mhd形式のファイルとして保存 11>>> spacinglist = [] 12>>> imglist = [] 13>>> raw_image = sitk.GetArrayFromImage(itkimage) 14>>> raw_array = np.asarray(raw_image, dtype=np.float64) 15>>> raw_array = raw_array.transpose(1, 2, 0) 16>>> imglist.append(raw_array) 17>>> imgdatas = np.asarray(imglist) 18>>> raw_spacing = itkimage.GetSpacing() 19>>> spacinglist.append(raw_spacing) 20>>> raw_array = imgdatas[0].transpose(2, 0, 1) 21>>> tmp_itkimg = sitk.Image(raw_array) 22Traceback (most recent call last): 23 File "<stdin>", line 1, in <module> 24 File "/Users/xxxx/opt/anaconda3/envs/xxxx/lib/python3.9/site-packages/SimpleITK/SimpleITK.py", line 3022, in __init__ 25 _SimpleITK.Image_swiginit(self, _SimpleITK.new_Image(*args)) 26TypeError: Wrong number or type of arguments for overloaded function 'new_Image'. 27 Possible C/C++ prototypes are: 28 itk::simple::Image::Image() 29 itk::simple::Image::Image(itk::simple::Image const &) 30 itk::simple::Image::Image(unsigned int,unsigned int,itk::simple::PixelIDValueEnum) 31 itk::simple::Image::Image(unsigned int,unsigned int,unsigned int,itk::simple::PixelIDValueEnum) 32 itk::simple::Image::Image(std::vector< unsigned int,std::allocator< unsigned int > > const &,itk::simple::PixelIDValueEnum,unsigned int)

すると上のように質問文と同じエラーが出力されましたので、現象を再現できたと仮定します。

コメントで紹介させていただいた https://github.com/hfarhidzadeh/DicomToMhd/blob/master/convert.py を参考に、tmp_itkimg = sitk.Image(raw_array)tmp_itkimg = sitk.GetImageFromArray(raw_array, isVector=False) に変更します。
また、tmp_itkimg.SetOrigin() を実行するためのコードも追加し、全体を以下のようなコードに変更します。

Python

1# 読み込んだ画像データをいったんndarrayに変換してから、再度mhd形式のファイルとして保存(変更後のコード) 2>>> spacinglist = [] 3>>> originlist = [] 4>>> imglist = [] 5>>> raw_image = sitk.GetArrayFromImage(itkimage) 6>>> raw_array = np.asarray(raw_image, dtype=np.float64) 7>>> raw_array = raw_array.transpose(1, 2, 0) 8>>> imglist.append(raw_array) 9>>> imgdatas = np.asarray(imglist) 10>>> raw_spacing = itkimage.GetSpacing() 11>>> spacinglist.append(raw_spacing) 12>>> raw_origin = itkimage.GetOrigin() 13>>> originlist.append(raw_origin) 14>>> raw_array = imgdatas[0].transpose(2, 0, 1) 15>>> tmp_itkimg = sitk.GetImageFromArray(raw_array, isVector=False) 16>>> tmp_itkimg.SetSpacing(spacinglist[0]) 17>>> tmp_itkimg.SetOrigin(originlist[0]) 18>>> sitk.WriteImage(tmp_itkimg, "new_file.mhd") 19 20# 書き出したものを再度読み込んで確認 21>>> reader.SetFileName("new_file.mhd") 22>>> image = reader.Execute() 23>>> sitk.Show(image)

今度は元の画像ファイルと同じものを別名で書き出すことができました。

なお

Python

1imgdatas = np.asarray(imglist)

の一文は無駄のように思います。imglistは単に複数のファイルを処理するために使われているだけなので、わざわざndarrayに変換しなくても以下のようにimglistをそのまま使えばよいと思います(こちらも正常に実行されることを確認済みです)。

Python

1... 2>>> raw_image = sitk.GetArrayFromImage(itkimage) 3>>> raw_array = np.asarray(raw_image, dtype=np.float64) 4>>> raw_array = raw_array.transpose(1, 2, 0) 5>>> imglist.append(raw_array) 6... 7>>> raw_array = imglist[0].transpose(2, 0, 1) 8>>> tmp_itkimg = sitk.GetImageFromArray(raw_array, isVector=False) 9...

投稿2021/06/11 15:42

編集2021/06/11 15:48
etherbeg

総合スコア1195

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

1999sin

2021/07/02 02:21

上記のコードを参考したところ無事作成することができました。本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問