11

私のシステムは Mac OS X v10.8.2 です。2560x500 の非圧縮 16 ビット TIFF イメージ (グレースケール、符号なし 16 ビット整数) がいくつかあります。最初に PIL (Homebrew、バージョン 1.7.8 経由でインストール) を使用してそれらをロードしようとします。

from PIL import Image
import numpy as np

filename = 'Rocks_2ptCal_750KHz_20ms_1ma_120KV_2013-03-06_20-02-12.tif'
img = Image.open(filename)

# >>> img
# <PIL.TiffImagePlugin.TiffImageFile image mode=I;16B size=2560x500 at 0x10A383C68>

img.show() 

# almost all pixels displayed as white.  Not correct.  
# MatLab, EZ-draw, even Mac Preview show correct images in grayscale.

imgdata = list(img.getdata()) 

# most values negative:
# >>> imgdata[0:10]
# [-26588, -24079, -27822, -26045, -27245, -25368, -26139, -28454, -30675, -28455]

imgarray = np.asarray(imgdata, dtype=np.uint16) 

# values now correct
# >>> imgarray
# array([38948, 41457, 37714, ..., 61922, 59565, 60035], dtype=uint16)

負の値は 65,536 ずれています...おそらく偶然ではありません。

ピクセルを変更するふりをして、PIL 経由で TIFF 画像に戻すと (配列を画像として戻すだけで):

newimg = Image.fromarray(imgarray)

エラーが発生します:

File "/usr/local/lib/python2.7/site-packages/PIL/Image.py", line 1884, in fromarray
    raise TypeError("Cannot handle this data type")
TypeError: Cannot handle this data type

Image.fromarray()PILのドキュメントでは見つかりません。経由でロードしようとしましImage.fromstring()たが、PIL ドキュメントが理解できず、例がほとんどありません。

上記のコードに示されているように、PIL はデータを として「検出」しているようI;16Bです。PILドキュメントからわかることから、モードIは次のとおりです。

*I* (32-bit signed integer pixels)

明らかに、それは正しくありません。

PIL が 16 ビット イメージをサポートしていないことを示唆する SX に関する多くの投稿を見つけました。pylibtiff を使用するための提案を見つけましたが、それは Windows のみだと思いますか?

Python でこれらの TIFF 画像を操作する「軽量」な方法を探しています。こんなに難しいことに驚いており、それが問題が他の人にとって明らかであると信じさせてくれます。

4

2 に答える 2

8

Matplotlib は 16 ビットの非圧縮 TIFF 画像を2行のコードで処理することがわかりました。

import matplotlib.pyplot as plt
img = plt.imread(filename)

# >>> img
# array([[38948, 41457, 37714, ..., 61511, 61785, 61824],
#       [39704, 38083, 36690, ..., 61419, 60086, 61910],
#       [41449, 39169, 38178, ..., 60192, 60969, 63538],
#       ...,
#       [37963, 39531, 40339, ..., 62351, 62646, 61793],
#       [37462, 37409, 38370, ..., 61125, 62497, 59770],
#       [39753, 36905, 38778, ..., 61922, 59565, 60035]], dtype=uint16)

出来上がり。Matplotlib は (私にとって) 重いモジュールであるため、これは「軽量」としての私の要件を満たしていないと思いますが、画像を Numpy 配列に入れるのは驚くほど簡単です。これは私には明らかではなかったので、これが他の誰かが解決策をすばやく見つけるのに役立つことを願っています.

于 2013-03-08T11:32:31.820 に答える