numpy 如何在python中读取一个大的tif文件?

yi0zb3m4  于 2022-12-04  发布在  Python
关注(0)|答案(4)|浏览(267)

我正在从http://oceancolor.gsfc.nasa.gov/DOCS/DistFromCoast/加载tiff文件

from PIL import Image
im = Image.open('GMT_intermediate_coast_distance_01d.tif')

数据量大(im.size=(36000, 18000) 1.3GB),常规转换不起作用;例如,imarray.shape返回()

import numpy as np 
imarray=np.zeros(im.size)
imarray=np.array(im)

如何将此tiff文件转换为numpy.array

bpzcxfmw

bpzcxfmw1#

可能你没有太多的内存用于此图像。你至少需要一些超过1.3GB的可用内存。
我不知道你是怎么处理图像的,你会把整个图像读入内存,但是我建议你一点一点地读,如果可能的话,这样可以避免破坏你的计算机。你可以使用Image.getdata(),它每次返回一个像素。
也可通过此链接阅读更多有关Image.open的信息:
http://www.pythonware.com/library/pil/handbook/

dgtucam1

dgtucam12#

到目前为止,我已经测试了许多替代品,但只有gdal工作总是即使巨大的16位图像。
您可以使用以下命令打开图像:

from osgeo import gdal
import numpy as np
ds = gdal.Open("name.tif")
channel = np.array(ds.GetRasterBand(1).ReadAsArray())
kadbb459

kadbb4593#

我有1到3 GB之间的大型tif文件,Image.open在手动将www.example.com源代码中MAX_IMAGE_PIXELS的值更改为任意大的数字后,Image.py:

from PIL import Image
im = np.asarray(Image.open("location/image.tif")
30byixjq

30byixjq4#

对于Python 32位2.7版,你会受到在给定时间内可以添加到堆栈的字节数的限制。一个选择是读入图像的各个部分,然后调整各个块的大小,并将它们重新组装成一个需要较少RAM的图像。
我建议使用libtiffopencv包。

import os
os.environ["PATH"] += os.pathsep + "C:\\Program Files (x86)\\GnuWin32\\bin"
import numpy as np
import libtiff
import cv2

tif = libtiff.TIFF.open("HUGETIFFILE.tif", 'r')
width = tif.GetField("ImageWidth")
height = tif.GetField("ImageLength")
bits = tif.GetField('BitsPerSample')
sample_format = tif.GetField('SampleFormat')

ResizeFactor = 10 #Reduce Image Size by 10
Chunks = 8 #Read Image in 8 Chunks to prevent Memory Error (can be increased for 
# bigger files)

ReadStrip = tif.ReadEncodedStrip
typ = tif.get_numpy_type(bits, sample_format)

#ReadStrip
newarr = np.zeros((1, width/ResizeFactor), typ)
for ii in range(0,Chunks):
    pos = 0
    arr = np.empty((height/Chunks, width), typ)
    size = arr.nbytes
    for strip in range((ii*tif.NumberOfStrips()/Chunks),((ii+1)*tif.NumberOfStrips()/Chunks)):
        elem = ReadStrip(strip, arr.ctypes.data + pos, max(size-pos, 0))
        pos = pos + elem

    resized = cv2.resize(arr, (0,0), fx=float(1)/float(ResizeFactor), fy=float(1)/float(ResizeFactor))

    # Now remove the large array to free up Memory for the next chunk
    del arr
    # Finally recombine the individual resized chunks into the final resized image.
    newarr = np.vstack((newarr,resized))

newarr = np.delete(newarr, (0), axis=0)
cv2.imwrite('resized.tif', newarr)

相关问题