ラスタをnumpy配列に完全にロードしますか?


26

パターン認識のためにDEMラスターでフィルターをチェックしようとしており、常に最後の行と列が欠落しています(like..20)。PILライブラリ、イメージのロードで試しました。次に、numpyを使用します。出力は同じです。

配列の値をチェックするとき(ArcCatalogでIDを使用してピクセルを選択する)、ループに何か問題があると思ったので、ピクセル値が配列に読み込まれていないことに気付きました。

したがって、単に開いて配列に入れ、配列から画像を保存するだけです:

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配列の制限についてだと思うので、配列は自動的に再形成されるか、そのようにsmthされます...だから例:

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

重要なのは、フィルタリングが必要なため、ブロックごとに読み取りたくない、異なるフィルタ、異なるサイズで何度も読みたくないということです。

回答:


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

知りません。PILは、Pythonに同梱されているので、十分に堅牢でなければなりません。しかし、imho geotiffは画像以上のものであり、たとえば多くのメタデータを保持します。PILは(やはりimho)適切なツールではありません。
ニックス

データを開くときに、diffの引用とスラッシュの要件が嫌いな場合があります。しかし、numpy配列をRasterに書き戻すのはどうでしょうか。PILライブラリで動作しますが、outputRaster.GetRasterBand(1).WriteArray(myarray)を使用すると無効なラスターが生成されます。
najuste12年

outBand.FlushCache()を使用して、データをディスクにフラッシュすることを忘れないでください。ここにいくつかのチュートリアルがあります:gis.usu.edu/~chrisg/python/2009
nickves

1
lists.osgeo.org/pipermail/gdal-dev/2010-January/023309.html」を確認してください-使い果たしたか、RAMになったようです。
ニックス

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]

これにより、すべてarrが寸法付きの3D numpy配列に読み込まれます[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これは、NumPyが配列を出力する方法です。これは変更できます。または、他の多くのNumpyトリックの中でも特に、配列のウィンドウをスライスして印刷します。
マイクT

一般的な質問。(シーン、高さ、幅、バンド)などの4つの次元である複数のシーンを含む単一の配列を出力する場合、このスニペットを変更するにはどうすればよいですか?
リカルドバロスロウレンソ

@RicardoBarrosLourenço4番目の次元(シーン?)は各ファイルに保存されていると思います。最初に空の4D numpy配列を作成し、次に各ファイル(シーン)をループして、それぞれの3D部分を挿入します。arr.transpose((1, 2, 0))各ファイルから(高さ、幅、バンド)を取得する必要がある場合があります。
マイク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ピクセルです。


ありがとう、しかし、私はより少ないライブラリとして使用しようとしています。
-najuste

1
@najuste OSは何ですか?MacおよびほとんどのLinuxフレーバーにはscipyおよびが付属していnumpyます。
チャドクーパー

どうやら...私はWindows、Winのさまざまなバージョンを使用しています。:/
najuste

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

Plzは間違いを見つけるのに役立ちます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.