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

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

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

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1545閲覧

.nifti形式の画像表示をすると90度回転している

tiroha

総合スコア109

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/10/29 07:33

編集2021/11/04 10:42

下記のコードでtiff形式からnifti形式に変換し、napariでnifti画像を表示させると、90度回転した画像が表示されます。
コードを追っても、そんな命令をしていないのですが。。。
見落としてますか?
90度回転はなしの状態にしたいです。
変換前のtiff画像は何枚も画像を重ねています。(gif画像のようなもの)

python

1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3""" 4tif_to_nii 5command line executable to convert a directory of tif images 6(from one image) to a nifti image stacked along a user-specified axis 7call as: python tif_to_nii.py /path/to/tif/ /path/to/nifti 8(append optional arguments to the call as desired) 9Author: Jacob Reinhold (jacob.reinhold@jhu.edu) 10""" 11 12import argparse 13from glob import glob 14import os 15from pathlib import Path 16import sys 17 18from PIL import Image 19import nibabel as nib 20import numpy as np 21 22 23def arg_parser(): 24 parser = argparse.ArgumentParser(description='merge 2d tif images into a 3d image') 25 parser.add_argument('img_dir', type=str, 26 help='path to tiff image directory') 27 parser.add_argument('out_dir', type=str, 28 help='path to output the corresponding tif image slices') 29 parser.add_argument('-a', '--axis', type=int, default=2, 30 help='axis on which to stack the 2d images') 31 return parser 32 33 34def split_filename(filepath): 35 path = os.path.dirname(filepath) 36 filename = os.path.basename(filepath) 37 base, ext = os.path.splitext(filename) 38 if ext == '.gz': 39 base, ext2 = os.path.splitext(base) 40 ext = ext2 + ext 41 return path, base, ext 42 43 44def main(): 45 try: 46 args = arg_parser().parse_args() 47 img_dir = Path(args.img_dir) 48 fns = sorted([str(fn) for fn in img_dir.glob('*.tif*')]) 49 if not fns: 50 raise ValueError(f'img_dir ({args.img_dir}) does not contain any .tif or .tiff images.') 51 imgs = [] 52 for fn in fns: 53 _, base, ext = split_filename(fn) 54 img = np.asarray(Image.open(fn)).astype(np.float32).squeeze() 55 ''' 56 if img.ndim != 2: 57 raise Exception(f'Only 2D data supported. File {base}{ext} has dimension {img.ndim}.') 58 ''' 59 imgs.append(img) 60 img = np.stack(imgs, axis=args.axis) 61 nib.Nifti1Image(img,None).to_filename(os.path.join(args.out_dir, f'{base}.nii.gz')) 62 return 0 63 except Exception as e: 64 print(e) 65 return 1 66 67 68if __name__ == "__main__": 69 sys.exit(main()) 70

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

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

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

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

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

jbpb0

2021/10/29 10:41 編集

変換前のtiffファイルが回転していて、それを無視してデータのみ読み込んで変換してファイル保存してるため、変換時に回転してしまったように見える、ということはありませんでしょうか? tiffファイルはOrientationタグの設定で、ファイル中のデータの本当の並び順とビューアで見たときの見た目の向きを変えることができるため、tiffファイルの中の本当のデータの並び順はビューアで見たときの方向の通りとは限りません 参考 http://hackmylife.net/archives/7400448.html https://gigazine.net/news/20191208-python-exif-orientation/
tiroha

2021/11/02 01:27

どうすれば、tiffファイルを回転させないで保存できますか?
jbpb0

2021/11/02 03:03

> どうすれば、tiffファイルを回転させないで保存 そのtiffファイルのOrientationタグがどうなってるのか(tiffファイルが回転してるのか)を、確認したのでしょうか? まだでしたら、下記を行なって、確認してみてください https://dabiyone.com/misc/mia023.html の「PilExifTag00.py」で、 rawdic = pilimage._getexif() ↓ 修正 rawdic = pilimage.getexif() だけ変えて(もちろん画像ファイル名は実際に合わせて)実行したら、tiffファイルのタグの一覧が表示されます その中に「Orientation」があるか探して、あれば値を確認します
jbpb0

2021/11/02 03:17

上記を確認した結果が、もしOrientationタグがあって、値が「1」以外ならですが、 https://teratail.com/questions/366680 を見たら、そのtiffファイルはjpgファイルやpngファイルから変換したもののようなので、変換前のjpgファイルやpngファイルも同様にしてOrientationタグがあるか探して、あれば値を確認してみてください
tiroha

2021/11/02 04:27

実行すると、 <class 'PIL.TiffImagePlugin.TiffImageFile'> <class 'PIL.Image.Exif'> と出てきて、orientaionタグは見当たりません。
jbpb0

2021/11/02 04:47 編集

それだけですか? 当方で適当なtiffファイルで実行したら、その下にかなりの行数が表示されるのですけど 最初の3行だけ載せます (こんな感じのが30行くらい表示されます) 256 : ImageWidth : 7087 : <class 'int'> 257 : ImageLength : 9449 : <class 'int'> 258 : BitsPerSample : (8, 8, 8, 8) : <class 'tuple'> もしOrientationタグがあれば、下記のように「274」から始まる行です 274 : Orientation : 1 : <class 'int'>
tiroha

2021/11/02 05:10

全然でないです。。。 最後の部分をこのように書き換えたのですが、これが間違いですかね? file1 = "train_tiff/Input/1~5.tiff" file2 = "train_tiff/Input/1~5.tiff" edic = get_exif_dic(file2)
jbpb0

2021/11/02 05:29

「train_tiff/Input」に「1~5.tiff」という名前のファイルがあるのですか? 変換前のjpgファイルかpngファイルでも、同様に確認してみてください
tiroha

2021/11/02 05:31

そうです。 確認してみます。
tiroha

2021/11/02 05:33

jpgでも同じ結果しか出力されません。
tiroha

2021/11/02 05:45

ダウンロードした画像ではたくさんの行が出力されました。 何が違うのでしょう?
jbpb0

2021/11/02 05:54

質問者さんが扱ってる画像ファイルには、Exifデータが付いてないのでしょう その場合は、Orientationタグが付いていたから回転して見えていた、という説は無くなりますね そうなると、怪しいのはtiffからniftiに変換してるところかな?? 下記を見ると、「affine」次第で向きが変えられるみたいなので http://meg.aalip.jp/python/BrainVISA_nibabel.html https://nshalnote.com/?p=352
jbpb0

2021/11/03 00:54 編集

当方で変換し確認したら、変換後に普通の画像として見たら方向は合ってましたが、 http://meg.aalip.jp/python/BrainVISA_nibabel.html https://nshalnote.com/?p=352 に記載の表示例のように左下を座標原点にして表示したら、上下が逆になりました どちらの場合でも、90°回転ではありませんでした 以下、確認した手順を書きます nifti画像は扱ったこと無いので、手順が間違ってるかも http://icb-lab.naist.jp/members/yoshi/ouec_lecture/image_recognition/image_files/len_std.jpg をダウンロードし、Exifデータが付いて無いことを確認 Pythonで下記を実行して、jpgをグレースケールのtiffに変換 from PIL import Image img = Image.open("len_std.jpg").convert("L") img.save("len_std.tiff") 「tin」というディレクトリを作り、そこにtiffファイルを置き、tiffファイルを複数にコピー 「nout」というディレクトリを作る (中は空) 質問に掲載のコードを実行して、tiffからniftiに変換 python tif_to_nii.py tin nout Pythonで下記を実行して、niftiを表示 import matplotlib.pyplot as plt import nibabel as nib import napari imgn = nib.load("./nout/len_std.nii.gz") imgn0 = imgn.get_fdata()[:, :, 0] # 普通の画像として表示:元画像と同じ向き plt.imshow(imgn0, cmap='gray') plt.show() # 左下を座標原点にして表示:元画像と上下が逆 plt.imshow(imgn0, cmap='gray', origin='lower') plt.show() # napariで表示:元画像と同じ向き viewer = napari.view_image(imgn0)
jbpb0

2021/11/03 00:58

当方でnapariで表示させたら、元画像と同じ向きでした 上記の手順に、その手順も追記しました > napariでnifti画像を表示させると、90度回転した画像が表示 とならないのは、当方の確認手順が間違ってるのでしょうか?
tiroha

2021/11/03 04:12

ありがとうございます。 試してみます。
tiroha

2021/11/03 04:24

試してみたら、同じ向きで表示されました。 機械学習でこの画像を読み込みたいんですが、表示させるときだけ同じ向きになっている感じですかね? 普通にnapariで表示させると、90度回転した画像が表示されるので。
jbpb0

2021/11/03 13:56 編集

> 試してみたら、同じ向きで表示されました。 は、私の「2021/11/02 16:25」のコメントの手順で実行したら、tiffとniftiの向きは(napariで表示させても)一致していた、という意味ですか? もしそうなら、それと、 > napariで表示させると、90度回転した画像が表示される は、何がどのように違うのでしょうか? 私がコメントで提示したのと同じ手順で変換したら、napariで表示させても向きは変わらないと思うのですが、当方の確認の手順と、質問者さんがやってる手順は、どこかに違いがあるのでしょうか? > 普通にnapariで表示させると みたいなふわっとした表現だと、現象の再現ができません 当方でも現象が再現できるように、手順を具体的に提示してください どのようにしたら、画像が90°回転するのでしょうか?
tiroha

2021/11/04 06:36

jbpb0さんのコードを実行したら、正しく表示されました。(回転なし)viewer=napari.view_image(imgn0)までの手順で。 今、悩んでいるのは、 $python tif_to_nii.py tin nout で変換したあとの画像を $napari image.nii で表示させると、90度回転していました。 つまり、このコードを使わないで表示 import matplotlib.pyplot as plt import nibabel as nib import napari imgn = nib.load("./nout/len_std.nii.gz") imgn0 = imgn.get_fdata()[:, :, 0] # 普通の画像として表示:元画像と同じ向き plt.imshow(imgn0, cmap='gray') plt.show() # 左下を座標原点にして表示:元画像と上下が逆 plt.imshow(imgn0, cmap='gray', origin='lower') plt.show() # napariで表示:元画像と同じ向き viewer = napari.view_image(imgn0
jbpb0

2021/11/04 11:14

> $napari image.nii で表示させると、90度回転 その状態で表示されてるのと、元画像を良く見比べてみてください 単純に90°回転してるだけですか? 元画像の左右を逆にした上で、90°左(時計回りの逆)に回転してませんか? 当方で確認したら、そうなってました 質問者さんが90°回転してると思ってる状態で、napariのメニューの「View」→「Axes」→「Visible」をON(チェック有り)にしてみてください 画像の左上に二つの矢印が現れて、「矢印1」が下向きで、「矢印2」が右向きになってると思います ここからは推測ですが、「矢印1」が普通の画像の横方向の向き、「矢印2」が縦方向の向きに相当するもののような気がします もしそうなら、下記の対応関係になります ・普通の画像の横方向の画素の並びは左→右:napariのこの状態では「矢印1」の上→下 ・普通の画像の縦方向の画素の並びは上→下:napariのこの状態では「矢印2」の左→右 つまり、画素の並びの縦横が、普通の画像とは逆に解釈されて表示されているのではないか、ということです (あくまでも現象からの推測で、もし当たっているとしても、そうなる理由は分かりませんが)
guest

回答1

0

自己解決

正常に表示するのはできたが、保存が上手く行ったかはわからない。
tiffファイルを使うのが良い。

投稿2022/01/21 06:04

tiroha

総合スコア109

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問