是否将栅格完全加载到numpy数组中?


26

我一直在尝试检查我在DEM栅格上的过滤器以进行模式识别,并且它总是导致缺少最后一行和最后一列(如..20)。我已经尝试了PIL库,图像加载。然后用numpy。输出是相同的。

我以为我的循环出了点问题,当检查数组中的值时(只是用ArcCatalog中的Identification选择像素),我意识到像素值未加载到数组中。

因此,只需打开,放入数组并保存数组中的图像即可:

a=numpy.array(Image.open(inraster)) #raster is .tif Float32, size 561x253
newIm=Image.new(Im.mode, Im.size)
Image.fromarray(a).save(outraster)

导致删除最后的行和列。抱歉,无法发布图片

任何人都可以帮助理解为什么?并建议一些解决方案?

编辑:

因此,在伙计们的帮助下,我成功地将小型栅格加载到numpy数组中,但是当图像较大时,我开始出现错误。我想这是关于numpy数组的限制,因此数组会像这样自动重塑或变形……所以ex:

Traceback (most recent call last):
  File "<pyshell#36>", line 1, in <module>
    ima=numpy.array(inDs.GetRasterBand(1).ReadAsArray())
  File "C:\Python25\lib\site-packages\osgeo\gdal.py", line 835, in ReadAsArray
    buf_xsize, buf_ysize, buf_obj )
  File "C:\Python25\lib\site-packages\osgeo\gdal_array.py", line 140, in BandReadAsArray
    ar = numpy.reshape(ar, [buf_ysize,buf_xsize])
  File "C:\Python25\lib\site-packages\numpy\core\fromnumeric.py", line 108, in reshape
    return reshape(newshape, order=order)
ValueError: total size of new array must be unchanged

关键是我不想逐块读取数据,因为我需要过滤,需要使用不同的过滤器,不同的大小来多次读取。

Answers:


42

如果您有python-gdal绑定:

import numpy as np
from osgeo import gdal
ds = gdal.Open("mypic.tif")
myarray = np.array(ds.GetRasterBand(1).ReadAsArray())

这样就完成了:

myarray.shape
(2610,4583)
myarray.size
11961630
myarray
array([[        nan,         nan,         nan, ...,  0.38068664,
     0.37952521,  0.14506227],
   [        nan,         nan,         nan, ...,  0.39791253,
            nan,         nan],
   [        nan,         nan,         nan, ...,         nan,
            nan,         nan],
   ..., 
   [ 0.33243281,  0.33221543,  0.33273876, ...,         nan,
            nan,         nan],
   [ 0.33308044,  0.3337177 ,  0.33416209, ...,         nan,
            nan,         nan],
   [ 0.09213851,  0.09242494,  0.09267616, ...,         nan,
            nan,         nan]], dtype=float32)

是的,对于gdal来说,我想我没有问题,但是我正在尝试使用较少的库...而且numpy在“搜索时”看来非常受欢迎。确实有任何想法,为什么numpy / PIL停止加载???
najuste 2012年

我不知道。PIL应该足够健壮,因此它随python一起提供。但是,imho geotiff不仅仅是图像-例如,它们包含大量元数据-并且PIL并不是(再次恕我直言)正确的工具。
尼克斯2012年

打开数据时,我有时有时会讨厌那些引号和斜杠要求。但是将numpy数组写回Raster呢?它的工作原理与PIL库,但使用outputRaster.GetRasterBand(1).WriteArray(myarray的)产生无效的光栅..
najuste

不要忘记使用outBand.FlushCache()将数据刷新到磁盘。您可以在这里找到一些教程:gis.usu.edu/~chrisg/python/2009
nickves


21

您可以使用rasterio与NumPy数组接口。要将栅格读取到数组:

import rasterio

with rasterio.open('/path/to/raster.tif', 'r') as ds:
    arr = ds.read()  # read all raster values

print(arr.shape)  # this is a 3D numpy array, with dimensions [band, row, col]

这将把所有内容读入3D numpy数组arr,并带有尺寸[band, row, col]


这是一个高级示例,用于读取,编辑像素,然后将其保存回栅格中:

with rasterio.open('/path/to/raster.tif', 'r+') as ds:
    arr = ds.read()  # read all raster values
    arr[0, 10, 20] = 3  # change a pixel value on band 1, row 11, column 21
    ds.write(arr)

栅格将在“ with”语句的末尾写入并关闭。


当我写print(arr)时为什么看不到所有值。它使用...,...,?分隔值。
穆斯塔法·乌萨(MustafaUçar),

@MustafaUçar这是NumPy打印数组的方式,您可以对其进行修改。或切片阵列的一个窗口进行打印,以及其他许多Numpy技巧。
Mike T

一个普遍的问题。如果要输出具有多个场景的单个数组,且场景为四个维度(场景,高度,宽度,带),则应如何修改此代码段?
里卡多·巴罗斯·洛伦索

@RicardoBarrosLourenço我猜您的第四个维度(场景?)存储在每个文件中。我先填充一个空的4D numpy数组,然后遍历每个文件(场景)并插入每个文件的3D部分。您可能需要arr.transpose((1, 2, 0))从每个文件中获取(高度,宽度,带)。
Mike T

@MikeT这个人口会是什么样的np.append()
里卡多·巴罗斯·洛伦索

3

授予我正在阅读一个普通的旧png图像,但这可以使用scipy(imsave尽管使用PIL):

>>> import scipy
>>> import numpy
>>> img = scipy.misc.imread("/home/chad/logo.png")
>>> img.shape
(81, 90, 4)
>>> array = numpy.array(img)
>>> len(array)
81
>>> scipy.misc.imsave('/home/chad/logo.png', array)

我得到的png也是81 x 90像素。


谢谢,但是我正在尝试使用更少的库。.现在,我可以使用gdal + numpy ...(希望没有PIL)实现它。
najuste 2012年

1
@najuste正在使用什么操作系统?Mac和大多数Linux风格都随附于scipynumpy
乍得·库珀

显然...我在Windows上使用Win的各种版本。:/
najuste 2012年

2

我使用gdal的解决方案如下所示。我认为这是非常可重用的。

import gdal
import osgeo.gdalnumeric as gdn

def img_to_array(input_file, dim_ordering="channels_last", dtype='float32'):
    file  = gdal.Open(input_file)
    bands = [file.GetRasterBand(i) for i in range(1, file.RasterCount + 1)]
    arr = np.array([gdn.BandReadAsArray(band) for band in bands]).astype(dtype)
    if dim_ordering=="channels_last":
        arr = np.transpose(arr, [1, 2, 0])  # Reorders dimensions, so that channels are last
    return arr

0

我正在使用158个波段的高光谱图像。我想计算栅格。但我明白了

import gdal # Import GDAL library bindings
from osgeo.gdalnumeric import *
from osgeo.gdalconst import *
import pylab as plt
import numpy as np
import xlrd
# The file that we shall be using
# Needs to be on current directory
filename = ('C:/Users/KIFF/Desktop/These/data/Hyperion/10th_bandmathref')
outFile = ('C:/Users/KIFF/Desktop/These/data/Hyperion/Math')
XLS=('C:/Users/KIFF/Desktop/These/data/Coef/bcoef.xlsx')
wb = xlrd.open_workbook(XLS)
sheet = wb.sheet_by_index(0)
sheet.cell_value(0, 0)


g = gdal.Open(filename, GA_ReadOnly)

# g should now be a GDAL dataset, but if the file isn't found
# g will be none. Let's test this:
if g is None:
    print ("Problem opening file %s!" % filename)
else:
    print ("File %s opened fine" % filename )

#band_array = g.ReadAsArray()
#print(band_array)
print ("[ RASTER BAND COUNT ]: ", g.RasterCount)

for band in range( g.RasterCount ):
    print (band)
    band += 1
    outFile = ('C:/Users/KIFF/Desktop/These/data/Results/Temp/Math_1_sur_value'+str(band)+'.tiff')
    #print ("[ GETTING BAND ]: ", band )
    srcband = g.GetRasterBand(band)
    if srcband is None:
        continue
    data1 = BandReadAsArray(srcband).astype(np.float)
    print(data1)
   # for i in range(3,sheet.nrows):
    b=sheet.cell_value(band+2,1)
    #print(b)
    dataOut = (1/data1)
    driver = gdal.GetDriverByName("ENVI")
    dsOut = driver.Create(outFile, g.RasterXSize, g.RasterYSize, 1)
    CopyDatasetInfo(g,dsOut)
    bandOut=dsOut.GetRasterBand(1)
    BandWriteArray(bandOut, dataOut)

因为print(data1)我只有一些“ 1”,但实际值是一些浮点数

0
[[1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]
 ...
 [1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]]
1
[[1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]
 ...
 [1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]]
2

像素值0,139200

请帮助找出错误

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.