Soru Python'da TIFF'lerle (içe aktarma, dışa aktarma) numpy kullanarak çalışma


TIFF görüntülerini numpy dizilerine açıp içe aktarabilen bir python rutinine ihtiyacım var, böylece içerilen verileri analiz edebilir ve değiştirebilir ve daha sonra tekrar TIFF'ler olarak kaydedebilirim. (Temelde gri tonlamada, piksel başına ilgili değerleri temsil eden ışık yoğunluğu haritalarıdır)

Bir şey bulmaya çalıştım, ancak TIFF ile ilgili PIL yöntemleri hakkında bir belge yok. Ben bunu anlamaya çalıştım, ancak sadece kötü mod / dosya türü desteklenmeyen hatalar var.

Burada kullanmak için neye ihtiyacım var?


44
2017-09-27 13:01


Menşei




Cevaplar:


İlk olarak, bir test TIFF resmini indirdim bu sayfa denilen a_image.tif. Sonra PIL ile şu şekilde açtım:

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

Bu gökkuşağı görüntüsünü gösterdi. Sayısal bir diziye dönüştürmek için, bu kadar basit:

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

Görüntünün boyutunun ve dizinin şeklinin eşleştiğini görebiliriz:

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

Ve dizi içerir uint8 değerler:

>>> 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)

Diziyi değiştirmeyi tamamladıktan sonra, aşağıdaki gibi bir PIL resmine dönüştürebilirsiniz:

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

60
2017-09-27 15:55



veri türleri ile sorun yaşıyorum. bazıları için iyi çalışıyor, örneğin. dizimde numpy.int16 numaraları varsa, ancak numpy.uint16 için image.fromarray verimleri: "TypeError: Bu veri türü işlenemiyor" - Jakob
Köşedeki kaynağa bakıldığında, işaretsiz 16 bitlik dizileri ele almıyor gibi görünüyor. - jterrace


TIFF dosyalarını okumak için matplotlib kullanıyorum:

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

ve I tip olacak ndarray.

Belgelere göre, aslında TIFF'leri ele alırken sahnelerin arkasında çalışan PIL, matplotlib'in yalnızca PNG'leri yerel olarak okurken, ama bu benim için iyi çalışıyor.

Ayrıca bir plt.imsave kaydetme işlevi.


36
2017-09-27 13:10



Bu, TIFF'lerle çalışmak için en kolay yoldur! Bir düzine yol denedim ve tüm bunlar bilet oldu. Kesinlikle kesin! - zachd1_618
görüntüleme kısmı hakkında nasıl? - Monica Heddneck


Bunu yapmak için GDAL'ı da kullanabilirsiniz. Bunun bir jeo-uzamsal araç olduğunu anlıyorum, ama hiçbir şey bir kartografik ürüne sahip olmanızı gerektirmiyor.

Windows için önceden derlenmiş GDAL ikili dosyalarına bağlantı (burada pencereleri varsayarak) http://www.gisinternals.com/sdk/

Diziye erişmek için:

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()

12
2017-09-27 14:33



tek bir TIF veya çok sayfalı TIF için yukarıdaki kod nedir? N-bitlere 16 bit tiff istifini yüklemek için gdal kullanmak istiyorum. - user391339
Bu, giriş veri türünde okumalı veya her şeyi numpy'nin float64 değerine taşımalıdır. Ekleyebilirsiniz .astype(sometype)sonuna çağrı ReadAsArray() yayınlamak için çağrı. Bunun bir kopya oluşturup oluşturmadığından emin değilsiniz (sadece test etmediniz). - Jzl5325
@Chikinn Şu kaynaktan: stackoverflow.com/review/suggested-edits/17962780  xrange yazım hatası yok xrange python 2 versiyonu range. Bu düzenlemeyi kabul ettim, çünkü python 3, python 2 olmadığında hala aktif olarak geliştiriliyor. - abccd


pylibtiff PIL'den daha iyi çalıştı renkli görüntüler, renk başına 8'den fazla biti desteklemez).

from libtiff import TIFF

tif = TIFF.open('filename.tif', mode='r')
# 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)

Eğer python3 iseniz yapamazsınız pip3 install libtiff. Bunun yerine, el ile yükleyin

git clone git@github.com:pearu/pylibtiff.git
python3 setup.py install

pylibtiff'in readme'si de bundan bahseder tifffile.pyama ben denemedim.


2
2017-07-05 00:30



Bu çok iyi. Şimdiye kadar, tifffile SciKit skimage.external.tifffile dahil ama aynı zamanda Mr. Christoph Gohlke tifffile.py indirmek eğer bir modül olarak ithal edilebilir - Zloy Smiertniy


Ayrıca kullanabilirsiniz pytiff Ben yazarım.

    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]

Oldukça küçük bir modüldür ve diğer modüller kadar çok özelliğe sahip olmayabilir, ancak kiremitli tiffleri ve bigtiff'i destekler, böylece büyük görüntülerin parçalarını okuyabilirsiniz.


2
2017-11-17 08:23





Görüntü yığınları durumunda kullanımı daha kolay buluyorum scikit-image okumak ve matplotlib göstermek veya kaydetmek için. Aşağıdaki kodla 16 bit TIFF görüntü yığınlarını ele aldım.

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
2017-07-01 14:24