numpyを使用してPythonでTIFF(インポート、エクスポート)を操作する


84

TIFF画像を開いてnumpy配列にインポートするには、Pythonメソッドが必要です。これにより、ピクセルデータを分析および変更して、TIFFとして再度保存できます。(これらは基本的にグレースケールの光強度マップであり、ピクセルごとのそれぞれの値を表します)

TIFFに関するPILメソッドに関するドキュメントが見つかりませんでした。私はそれを理解しようとしましたが、「悪いモード」または「ファイルタイプがサポートされていません」というエラーしか発生しませんでした。

ここで何を使用する必要がありますか?

回答:


103

まず、私はからテストTIFF画像ダウンロードこのページと呼ばれるがa_image.tif。次に、次のようにPILで開きました。

>>> from PIL import Image
>>> im = Image.open('a_image.tif')
>>> im.show()

これは虹のイメージを示しています。numpy配列に変換するには、次のように簡単です。

>>> import numpy
>>> imarray = numpy.array(im)

画像のサイズと配列の形状が一致していることがわかります。

>>> imarray.shape
(44, 330)
>>> im.size
(330, 44)

また、配列には次のuint8値が含まれています。

>>> imarray
array([[  0,   1,   2, ..., 244, 245, 246],
       [  0,   1,   2, ..., 244, 245, 246],
       [  0,   1,   2, ..., 244, 245, 246],
       ..., 
       [  0,   1,   2, ..., 244, 245, 246],
       [  0,   1,   2, ..., 244, 245, 246],
       [  0,   1,   2, ..., 244, 245, 246]], dtype=uint8)

配列の変更が完了したら、次のように配列をPILイメージに戻すことができます。

>>> Image.fromarray(imarray)
<Image.Image image mode=L size=330x44 at 0x2786518>

4
データ型に問題があります。配列にnumpy.int16番号がある場合、一部のfeでは正常に機能しますが、numpy.uint16 image.fromarrayの場合、「TypeError:このデータ型を処理できません」
Jakob

4
fromarrayのソースを見ると、符号なし16ビット配列を処理しているようには見えません。
jterrace 2011

2020年6月現在の@JakobPILは、1色あたり8ビットを超えるカラー画像をサポートしていません。別のライブラリを使用する必要があります(または自分で機能を提供する必要があります)。
ボリス

56

TIFFファイルの読み取りにmatplotlibを使用します。

import matplotlib.pyplot as plt
I = plt.imread(tiff_file)

そしてI型になりますndarray

ドキュメントによると、matplotlibはPNGをネイティブに読み取るだけなので、TIFFを処理するときに舞台裏で機能するのは実際にはPILですが、これは私にとっては問題なく機能しています。

plt.imsave保存する機能もあります。


これは、TIFFを操作する最も簡単な方法です。十数通りの方法を試しましたが、これはすべてチケットでした。確かに賛成!
zachd1_618 2012年

視聴部分はどうですか?
Monica Heddneck 2018年

5
変更された戦略をmatplotlibのようだ:ValueError: Only know how to handle extensions: ['png']; with Pillow installed matplotlib can handle more images
strpeter

17

GDALを使用してこれを行うこともできます。これは地理空間ツールキットであると認識していますが、地図作成製品を用意する必要はありません。

Windows用にプリコンパイルされたGDALバイナリへのリンク(ここではWindowsを想定) http://www.gisinternals.com/sdk/

アレイにアクセスするには:

from osgeo import gdal

dataset = gdal.Open("path/to/dataset.tiff", gdal.GA_ReadOnly)
for x in range(1, dataset.RasterCount + 1):
    band = dataset.GetRasterBand(x)
    array = band.ReadAsArray()

上記のコードは単一のTIFまたは複数ページのTIFですか?gdalを使用して16ビットのtiffスタックをnparrayにロードしたいと思います。
user391339 2015年

これは、入力データ型を読み込むか、すべてをnumpyのfloat64に移動する必要があります。キャスト.astype(sometype)するReadAsArray()通話の最後に通話を追加できます。これがコピーを作成するかどうかわからない(テストしていないだけです)。
jzl5325 2015年

@Chikinnレビューから:stackoverflow.com/review/suggested-edits/17962780 xrangeはタイプミスでxrangeはなく、Python2バージョンのrangeです。python 3はまだ積極的に改善されていますが、python 2は改善されていないため、この編集を受け入れました。
abccd 2017年

12

pylibtiffは、2020年6月の時点で1色あたり8ビットを超えるカラー画像をサポートしていないPILよりもうまく機能しました。

from libtiff import TIFF

tif = TIFF.open('filename.tif') # open tiff file in read mode
# read an image in the currect TIFF directory as a numpy array
image = tif.read_image()

# read all images in a TIFF file:
for image in tif.iter_images(): 
    pass

tif = TIFF.open('filename.tif', mode='w')
tif.write_image(image)

pylibtiffはでインストールできます

pip3 install numpy libtiff

pylibtiffのreadmeにも言及されていますtifffileが、私は試していません。表面上はオープンソースですが、コードはもうどこにも利用できないと思います(PyPIパッケージから手動で抽出する以外)。


2
これはとても良いです。今では、tifffileはSciKitのskimage.external.tifffileに含まれていますが、氏クリストフゴールケからtifffile.pyをダウンロードする場合、それはまた、モジュールとしてインポートすることができます
lesolorzanov

7

私が作者であるpytiffを使用することもできます。

    import pytiff

    with pytiff.Tiff("filename.tif") as handle:
        part = handle[100:200, 200:400]

    # multipage tif
    with pytiff.Tiff("multipage.tif") as handle:
        for page in handle:
            part = page[100:200, 200:400]

これはかなり小さなモジュールであり、他のモジュールほど多くの機能を備えていない可能性がありますが、タイル状のtiffとbigtiffをサポートしているため、大きな画像の一部を読み取ることができます。


この機能はまさに私が必要としているものです!(大きなファイルの小さなチャンクを読み取ることができる)。ただし、pip installを実行しようとすると、gccエラーが発生します
FractalyJun

エラーメッセージで問題を作成した場合は、問題を特定できるかどうかを確認します。
hnfl

はい、私も興味がありますが、インストールしようとするとエラーが発生しました。私はpipを使ってそうしました-WindowsとUbuntuの下で。それが機能しないのは残念です!私はここでの問題を作成しました:github.com/FZJ-INM1-BDA/pytiff/issues/15
Dobedani

6

画像スタックの場合、scikit-image読みやすく、matplotlib表示または保存しやすいと思います。次のコードで16ビットTIFF画像スタックを処理しました。

from skimage import io
import matplotlib.pyplot as plt

# read the image stack
img = io.imread('a_image.tif')
# show the image
plt.imshow(mol,cmap='gray')
plt.axis('off')
# save the image
plt.savefig('output.tif', transparent=True, dpi=300, bbox_inches="tight", pad_inches=0.0)

0

OpenImageIOへのPythonバインディングを使用することをお勧めします。これは、vfxの世界でさまざまな画像形式を処理するための標準です。PILと比較して、さまざまな種類の圧縮を読み取る際の信頼性が高いことがわかりました。

import OpenImageIO as oiio
input = oiio.ImageInput.open ("/path/to/image.tif")

コンパイラがすでにない限り、境界線をWindowsにインストールすることはできません。
ジミーカーター
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.