Pythonでチャンネルあたり16ビット、3チャンネルのTIFFイメージをインポートする方法はありますか?
TIFF形式を扱うときに、チャネルごとに16ビットの深さを保持する方法をまだ見つけていません。役に立つ魂が解決することを願っています。
ここに、成功せずに今まで試した結果と結果のリストを示します。
import numpy as np
import PIL.Image as Image
import libtiff
import cv2
im = Image.open('a.tif')
# IOError: cannot identify image file
tif = libtiff.TIFF.open('a.tif')
im = tif.read_image()
# im only contains one of the three channels. im.dtype is uint16 as desired.
im = []
for i in tif.iter_images():
# still only returns one channel
im = np.array(cv2.imread('a.tif'))
# im.dtype is uint8 and not uint16 as desired.
# specifying dtype as uint16 does not correct this
これまでのところ、私が見つけた唯一の解決策は、ImageMagickで画像をPNGに変換することです。その後、沼地の標準matplotlib.pyplot.imread
は、PNGファイルを問題なく読み取ります。
私が抱えている別の問題は、numpy配列を16ビットPNGファイルとして保存することです。
特にRGB以外のディスクイメージへの書き戻しに関しては機能が制限されていますが、 Christoph Gohlkeのtifffile
module 3チャネル16ビットTIFFを問題なく読み取り、テストしたばかりです。それ:
>>> import tifffile as tiff
>>> a = tiff.imread('Untitled-1.tif')
>>> a.shape
(100L, 100L, 3L)
>>> a.dtype
dtype('uint16')
そして、Photoshopは、私が何をするかについて文句を言うことなく読み取ります:
>>> tiff.imsave('new.tiff', a)
@ Jaime による答えは機能します。
その間、OpenCVで _cv2.imread
_ を使用して問題を解決することもできました。
デフォルトでは、_cv2.imread
_は、質問に示すように、_a.tif
_の16ビットの3チャネルイメージを8ビットに変換します。
_cv2.imread
_は、ファイル名(cv2.imread(filename[, flags])
)の後にフラグを受け入れます。このフラグは、読み込まれた画像のカラータイプを指定しますcf. ドキュメント :
そのため、以下は変換せずに画像を読み取ります。
_>>> im = cv2.imread('a.tif', -1)
>>> im.dtype
dtype('uint16')
>>> im.shape
(288, 384, 3)
_
OpenCVはR、G、Bチャネルを逆の順序で返すため、_im[:,:,0]
_はBチャネル、_im[:,:,1]
_はGチャネル、_im[:,:,2]
_はRチャネルです。
また、_cv2.imwrite
_は16ビットの3チャネルTIFFファイルを書き込むことができます。
_>>> cv2.imwrite('out.tif', im)
_
ImageMagickでビット深度を確認する:
_$ identify -verbose out.tif
Format: TIFF (Tagged Image File Format)
Class: DirectClass
Geometry: 384x288+0+0
Resolution: 72x72
Print size: 5.33333x4
Units: PixelsPerInch
Type: TrueColor
Base type: TrueColor
Endianess: MSB
Colorspace: sRGB
Depth: 16-bit
Channel depth:
red: 16-bit
green: 16-bit
blue: 16-bit
....
_
上記の2つの方法の追加の代替手段を見つけました。
scikit-image パッケージは、tifffile.py
とFreeImageの両方を使用し、それらを使用するプラグインとして指定して、16ビットの3チャネルTIFFファイルを読み取ることもできます。
tifffile.py
を使用した読み取りは、おそらく @ Jaime で示される方法でより簡単に行われますが、誰かがそれをやりたい場合にscikit-imageとともに使用する方法を示すと思いましたこの方法。
Ubuntuを使用している場合、FreeImageはapt
を使用してlibfreeimage3
として利用できます。
tifffile.py
プラグインオプションを使用する場合、tifffile.pyをskimage/io/_pluginsディレクトリにコピーする必要があります(f.ex.私の場合のフルパスは/usr/local/lib/python2.7/dist-packages/skimage/io/_plugins/
)。
>>> import skimage.io
>>> im = skimage.io.imread('a.tif', plugin='tifffile')
>>> im.dtype
dtype('uint16')
>>> im.shape
(288, 384, 3)
>>> im = skimage.io.imread('a.tif', plugin='freeimage')
>>> im.dtype
dtype('uint16')
>>> im.shape
(288, 384, 3)
TIFFファイルの作成:
>>> skimage.io.imsave('b.tif', im, plugin='tifffile')
>>> skimage.io.imsave('c.tif', im, plugin='freeimage')
ImageMagickを使用してb.tif
とc.tif
の両方のビット深度を確認すると、両方の画像の各チャンネルが16ビットであることがわかります。
私にとって、以前の選択肢は機能しませんでした。 1 GBの16ビット画像の読み取りに gdal を使用しました。
次のような画像を開くことができます:
from osgeo import gdal
import numpy as np
ds = gdal.Open("name.tif")
channel = np.array(ds.GetRasterBand(1).ReadAsArray())
サポートされているダイバー のリストがあり、データの書き込みに使用できます。
OpenImageIOへのpythonバインディングを使用することをお勧めします。これは、vfxドメイン(通常は16/32ビット)のさまざまな画像形式を処理するための標準です。
import OpenImageIO as oiio
input = oiio.ImageInput.open ("/path/to/image.tif")