numpy 배열에 래스터를 완전히로드 하시겠습니까?


26

패턴 인식을 위해 DEM 래스터에서 필터를 확인하려고 시도했으며 항상 마지막 행과 열이 누락되었습니다 (예 : 20) . PIL 라이브러리, 이미지로드로 시도했습니다. 그런 다음 numpy로. 출력은 동일합니다.

배열에서 값을 확인할 때 (Arrcatalog에서 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 배열의 한계에 관한 것이라고 가정하고 배열은 자동으로 모양이 바뀌거나 그런 것입니다 ... 그래서 예 :

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는 'while googling'에서 너무 인기가있는 것처럼 보였습니다. numpy / PIL 이로 드를 멈추는 이유는 무엇입니까 ???
najuste

모르겠어요 PIL은 파이썬과 함께 제공되도록 충분히 견고해야합니다. 그러나 imho geotiff는 이미지 이상의 것입니다. 예를 들어 많은 메타 데이터가 포함되어 있으며 PIL은 올바른 도구가 아닙니다 (다시 말하면).
nickves September

데이터를 열 때 난이도 인용 부호와 슬래시 요구 사항을 싫어하는 경우가 있습니다. 그러나 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)를 쓸 때 모든 값을 볼 수없는 이유는 무엇입니까? 이것으로 값을 분리합니다 ..., ...,?
Mustafa Uçar

@ MustafaUçar 이것은 NumPy가 배열을 인쇄하는 방법으로 수정 할 수 있습니다 . 또는 다른 많은 Numpy 트릭 중에서 인쇄 할 배열의 창을 슬라이스하십시오.
Mike T

일반적인 질문입니다. (장면, 높이, 너비, 밴드)와 같은 4 차원 인 다중 장면을 가진 단일 배열을 출력하려면이 스 니펫을 어떻게 수정해야합니까?
Ricardo Barros Lourenço

@ RicardoBarrosLourenço 네 번째 차원 (장면?)이 각 파일에 저장되어 있다고 생각합니다. 먼저 빈 4D numpy 배열을 채운 다음 각 파일 (장면)을 반복하고 각각의 3D 부분을 삽입합니다. 당신이해야 할 arr.transpose((1, 2, 0))각 파일에서 (높이, 폭, 밴드)를 얻을 수 있습니다.
Mike T

@MikeT이 인구는 np.append()?
Ricardo Barros Lourenço

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

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.