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.