โหลดแรสเตอร์ทั้งหมดลงในอาร์เรย์ numpy แล้วหรือยัง?


26

ฉันได้รับการพยายามที่จะตรวจสอบตัวกรองของฉันในแรสเตอร์ DEM สำหรับการรับรู้รูปแบบและมันมักจะมีผลในการหายไปแถวสุดท้ายและคอลัมน์ (like..20) ฉันลองห้องสมุด PIL แล้วโหลดภาพ จากนั้นด้วย numpy ผลลัพธ์เหมือนกัน

ฉันคิดว่ามีบางอย่างผิดปกติกับลูปของฉันเมื่อตรวจสอบค่าในอาร์เรย์ (แค่เลือกพิกเซลด้วย Identification ใน ArcCatalog) ฉันรู้ว่าค่าพิกเซลไม่ได้ถูกโหลดลงในอาร์เรย์

ดังนั้นเพียงแค่เปิดใส่เข้าไปในอาร์เรย์และบันทึกภาพจากอาร์เรย์:

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 array ดังนั้น array จะถูกเปลี่ยนรูปร่างโดยอัตโนมัติหรือ 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

ประเด็นคือฉันไม่ต้องการอ่านบล็อกโดยบล็อกตามที่ฉันต้องการกรองหลายครั้งด้วยตัวกรองที่แตกต่างกันขนาดแตกต่างกัน .. มีงานแก้ไขหรือฉันต้องเรียนรู้ rading โดยบล็อก: O

คำตอบ:


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 ดูเหมือนเป็นที่นิยมสำหรับ 'ขณะ googling' มีความคิดใด ๆ ทำไม numpy / PIL หยุดโหลด ???
najuste

ฉันไม่รู้ PIL ควรแข็งแกร่งพอที่จะส่งมาพร้อมกับ python แต่พิกัดทางภูมิศาสตร์ของ imho นั้นมากกว่าภาพพวกมันมีข้อมูลเมตามากมายเช่น PIL ไม่ใช่เครื่องมือที่เหมาะสม
nickves

บางครั้งฉันก็เกลียดข้อกำหนดใบเสนอราคาและเครื่องหมายทับเมื่อเปิดข้อมูล .. แต่การเขียนอาร์เรย์แบบ numpy กลับไปที่ Raster เป็นอย่างไร มันทำงานร่วมกับห้องสมุด PIL แต่ใช้ outputRaster.GetRasterBand (1) .WriteArray (myarray) สร้างแรสเตอร์ที่ไม่ถูกต้อง ..
najuste

อย่าลืมลบข้อมูลลงดิสก์ด้วย outBand.FlushCache () คุณสามารถค้นหาแบบฝึกหัดได้ที่นี่: gis.usu.edu/~chrisg/python/2009
nickves

1
ทำเครื่องหมายที่ " lists.osgeo.org/pipermail/gdal-dev/2010- มกราคม/023309.html " - ดูเหมือนว่าคุณมี RAM หมดแล้ว
nickves

21

คุณสามารถใช้rasterioเพื่อเชื่อมต่อกับ NumPy arrays หากต้องการอ่านแรสเตอร์ไปยังอาร์เรย์:

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]

นี้จะอ่านทุกอย่างที่เป็นอาร์เรย์ numpy 3D ที่มีมิติ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)

แรสเตอร์จะถูกเขียนและปิดท้ายที่"กับ" คำสั่ง


ทำไมเราไม่เห็นค่าทั้งหมดเมื่อฉันเขียนพิมพ์ (arr) มันแยกค่ากับสิ่งนี้ ... , ... ,?
Mustafa Uçar

@ MustafaUçarนี่เป็นวิธีที่ NumPy พิมพ์อาร์เรย์ซึ่งคุณสามารถแก้ไขได้ หรือแบ่งเป็นหน้าต่างของอาเรย์เพื่อพิมพ์ใน Numpy tricks อื่น ๆ
Mike T

คำถามทั่วไป หากฉันต้องการส่งออกอาเรย์เดี่ยวที่มีหลายฉากโดยมีสี่มิติเช่น (ฉาก, ความสูง, ความกว้าง, วงดนตรี) ฉันจะแก้ไขข้อมูลโค้ดนี้ได้อย่างไร
Ricardo Barros Lourenço

@ RicardoBarrosLourençoฉันเดาว่ามิติที่สี่ของคุณ (ฉาก?) ถูกเก็บไว้ในแต่ละไฟล์ ฉันจะเติมอาเรย์ 4D numpy อันว่างเปล่าก่อนจากนั้นวนซ้ำแต่ละไฟล์ (ฉาก) และแทรกส่วน 3 มิติของแต่ละไฟล์ คุณอาจต้อง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 ระบบปฏิบัติการอะไรอยู่ Mac และ Linux รสชาติส่วนใหญ่มาด้วยและscipy numpy
Chad Cooper

เห็นได้ชัดว่า ... ฉันใช้ Windows เป็นวินรุ่นต่างๆ : /
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

ฉันใช้ภาพ hyperspectral กับวงดนตรี 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

โปรดช่วยในการค้นหาความผิดพลาด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.