【GDAL學習】用GDAL讀取柵格資料
阿新 • • 發佈:2018-12-08
1.根據座標讀取遙感影像的單個畫素值
# week 4: get pixel values at a set of coordinates by reading in one pixel at a time import os, sys, time from osgeo import gdal from gdalconst import * # start timing startTime = time.time() # coordinates to get pixel values for xValues = [447520.0, 432524.0, 451503.0] yValues = [4631976.0, 4608827.0, 4648114.0] # set directory os.chdir('E:/data/GDAL/ospy_data4') # register all of the drivers gdal.AllRegister() # open the image ds = gdal.Open('aster.img', GA_ReadOnly) if ds is None: print('cannot open this file.') sys.exit(1) # get image size rows = ds.RasterYSize cols = ds.RasterXSize bands = ds.RasterCount # get georeference info transform = ds.GetGeoTransform() xOrigin = transform[0] yOrigin = transform[3] pixelWidth = transform[1] pixelHeight = transform[5] # loop through the coordinates for i in range(3): # get x,y x = xValues[i] y = yValues[i] # compute pixel offset xOffset = int((x - xOrigin) / pixelWidth) yOffset = int((y - yOrigin) / pixelHeight) # create a string to print out s = str(x) + ' ' + str(y) + ' ' + str(xOffset) + ' ' + str(yOffset) + ' ' # loop through the bands for j in range(bands): band = ds.GetRasterBand(j + 1) # read data and add the value to the string data = band.ReadAsArray(xOffset, yOffset, 1, 1) value = data[0, 0] s = s + str(value) + ' ' # print out the data string print(s) # figure out how long the script took to run endTime = time.time() print('The script took ' + str(endTime - startTime) + ' seconds.')
2.根據座標讀取遙感影像的單個畫素值,通過獲取影象所有畫素值獲得
# week 4:script to get pixel values at a set of coordinates by reading in entire bands from osgeo import gdal from gdalconst import * import os, sys, time # start timing startTime = time.time() # coordinates to get pixel values for xValues = [447520.0, 432524.0, 451503.0] yValues = [4631976.0, 4608827.0, 4648114.0] # set directory os.chdir('E:/data/GDAL/ospy_data4') # register all of the drivers gdal.AllRegister() # open the image ds = gdal.Open('aster.img', GA_ReadOnly) if ds is None: print('Cannot open aster.img') sys.exit(1) # get image size rows = ds.RasterYSize cols = ds.RasterXSize bands = ds.RasterCount # get georeference info transform = ds.GetGeoTransform() xOrigin = transform[0] yOrigin = transform[3] pixelWidth = transform[1] pixelHeight = transform[5] # create a list to store band data in bandList = [] # read in bands and store all the data in bandList for i in range(bands): band = ds.GetRasterBand(i + 1) data = band.ReadAsArray(0, 0, cols, rows) bandList.append(data) # loop through the coordinates for i in range(3): x = xValues[i] y = yValues[i] # compute pixel offset xOffset = int((x - xOrigin) / pixelWidth) yOffset = int((y - yOrigin) / pixelHeight) # create a string to print out s = str(x) + ' ' + str(y) + ' ' + str(xOffset) + ' ' + str(yOffset) + ' ' # loop through the bands and get the pixel value for j in range(bands): data = bandList[j] value = data[xOffset-1, yOffset-1] s = s + str(value)+' ' # print out the data string print(s) # figure out how long the script took to run endTime = time.time() print('The script took ' + str(endTime - startTime) + ' seconds.')
3.Assignment 4a:Read pixel values from an image
- Print out the pixel values for all three bands of aster.img at the points contained in sites.shp •
- Use any method of reading the raster data that you want, but I would suggest one pixel at a time (fastest in this case since we don't need much data)
1)自己寫的程式碼,現獲取所有sities的座標後再獲取全部的pixel values
# Assignment 4a: Read pixel values from an image
# write by myself
from osgeo import gdal
from gdalconst import *
import ogr, os, sys
# set the directory
os.chdir('E:/data/GDAL/ospy_data4')
# set the driver
driver = ogr.GetDriverByName('ESRI Shapefile')
# open the file
siteDS = driver.Open('sites.shp', 0)
if siteDS is None:
print('Cannot open sites.shp')
sys.exit(1)
# get the layer
siteLy = siteDS.GetLayer()
# get the feature
siteFe = siteLy.GetNextFeature()
# create lists to store the x,y coordination of the feature
sitePosX = []
sitePosY = []
# cycle the feature to get the x,y coordination
while siteFe:
geom = siteFe.GetGeometryRef()
fex = geom.GetX()
fey = geom.GetY()
sitePosX.append(fex)
sitePosY.append(fey)
siteFe.Destroy()
siteFe = siteLy.GetNextFeature()
# create a txt file to store result
txt = open('output.txt', 'w')
# register all of the drivers
gdal.AllRegister()
# open the image
asterDS = gdal.Open('aster.img', GA_ReadOnly)
if asterDS is None:
print('Cannot open aster.img')
sys.exit(1)
# get the image size
rows = asterDS.RasterYSize
cols = asterDS.RasterXSize
bands = asterDS.RasterCount
# get the georeference info
transform = asterDS.GetGeoTransform()
xOrigin = transform[0]
yOrigin = transform[3]
pixelWidth = transform[1]
pixelHeight = transform[5]
# get the pixel value of the coordination
for i in range(len(sitePosX)):
x = sitePosX[i]
y = sitePosY[i]
# get the offset
xOffset = int((x - xOrigin) / pixelWidth)
yOffset = int((y - yOrigin) / pixelHeight)
s = str(i + 1) + ' ' + str(x) + ' ' + str(y) + ' ' + str(xOffset) + ' ' + str(yOffset) + ' '
# get all bands of the pixel value
for j in range(bands):
band = asterDS.GetRasterBand(j + 1)
data = band.ReadAsArray(xOffset, yOffset, 1, 1)
value = data[0, 0]
s = s + str(value) + ' '
s = s + '\n'
# write to a text file
txt.write(s)
print(s)
# destroy datasource
siteDS.Destroy()
2)參考答案給的程式碼,每獲取一個site座標就獲取該座標的pixel value
import os, sys
try:
from osgeo import ogr, gdal
from osgeo.gdalconst import *
os.chdir('E:/data/GDAL/ospy_data4')
except ImportError:
import ogr, gdal
from gdalconst import *
os.chdir('E:/data/GDAL/ospy_data4')
# open the shapefile and get the layer
driver = ogr.GetDriverByName('ESRI Shapefile')
shp = driver.Open('sites.shp')
if shp is None:
print('Could not open sites.shp')
sys.exit(1)
shpLayer = shp.GetLayer()
# register all of the GDAL drivers
gdal.AllRegister()
# open the image
img = gdal.Open('aster.img', GA_ReadOnly)
if img is None:
print('Could not open aster.img')
sys.exit(1)
# get image size
rows = img.RasterYSize
cols = img.RasterXSize
bands = img.RasterCount
# get georeference info
transform = img.GetGeoTransform()
xOrigin = transform[0]
yOrigin = transform[3]
pixelWidth = transform[1]
pixelHeight = transform[5]
# loop through the features in the shapefile
feat = shpLayer.GetNextFeature()
while feat:
geom = feat.GetGeometryRef()
x = geom.GetX()
y = geom.GetY()
# compute pixel offset
xOffset = int((x - xOrigin) / pixelWidth)
yOffset = int((y - yOrigin) / pixelHeight)
# create a string to print out
s = feat.GetFieldAsString('ID') + ' '
# loop through the bands
for j in range(bands):
band = img.GetRasterBand(j + 1) # 1-based index
# read data and add the value to the string
data = band.ReadAsArray(xOffset, yOffset, 1, 1)
value = data[0, 0]
s = s + str(value) + ' '
# print out the data string
print(s)
# get the next feature
feat.Destroy()
feat = shpLayer.GetNextFeature()
# close the shapefile
shp.Destroy()
4.為了更有效率地讀取柵格,一種更好的方法是分塊讀取資料。資料檔案中給出了一個utils.py檔案中的GetBlockSize()函式可以實現獲取影象中的xBlockSize和yBlockSize,但是在我的電腦裡不能執行。於是嘗試手動定義xBlockSize和yBlockSize,更改了幾次數值發現程式執行結果都是一樣的,因此我認為手動賦值給xBlockSize和yBlockSize也是可行的。下面程式碼是迴圈分塊讀取柵格資料的樣例,具體原理可參見PPT
from osgeo import gdal
from gdalconst import *
import numpy as np
import os
import sys
import utils
os.chdir('E:/data/GDAL/ospy_data4')
gdal.AllRegister()
ds = gdal.Open('aster.img', GA_ReadOnly)
if ds is None:
print('Cannot open aster.img')
sys.exit(1)
rows = ds.RasterYSize
cols = ds.RasterXSize
bands = ds.RasterCount
band = ds.GetRasterBand(1)
# 由於utils.py檔案中找不到_gdal模組,因此以下三行程式碼不能使用
# xblocksize和yblocksize改為手動設定
# 更改了幾個值發現程式執行最終結果不變
# blockSizes = utils.GetBlockSize(band)
# xBlockSize = blockSizes[0]
# yBlockSize = blockSizes[1]
xBlockSize = 20
yBlockSize = 20
count = 0
for i in range(0, rows, yBlockSize):
if (i + yBlockSize) < rows:
numRows = yBlockSize
else:
numRows = rows - i
for j in range(0, cols, xBlockSize):
if (j + xBlockSize) < cols:
numCols = xBlockSize
else:
numCols = cols - j
data = band.ReadAsArray(j, i, numCols, numRows).astype(np.float)
mask = np.greater(data, 0)
count = count + np.sum(np.sum(mask))
print('Number of non-zero pixels: ', count)
5. Assignment 4b:
- Write a script to calculate the average pixel value for the first band in aster.img
- Read in the data one block at a time
- Do the calculation two ways :
- Including zeros in the calculation
- Ignoring zeros in the calculation
1)自己寫的程式碼
# Assignment 4b:Write a script to calculate the average pixel value for the first band in aster.img
# write by myself
# import models
from osgeo import gdal
from gdalconst import *
import numpy as np
import os
import sys
# set the directory
os.chdir('E:/data/GDAL/ospy_data4')
# register all drivers
gdal.AllRegister()
# open the file
ds = gdal.Open('aster.img', GA_ReadOnly)
if ds is None:
print('Cannot open aster.img')
sys.exit(1)
# get the raster size
rows = ds.RasterYSize
cols = ds.RasterXSize
bands = ds.RasterCount
# get the first band and set blocksize
band = ds.GetRasterBand(1)
xBlockSize = 10
yBlockSize = 10
sumIncludeZero = 0.0
zeroCount = 0
# cycle row blocksize
for i in range(0, rows, yBlockSize):
# set yblocksize
if (i + yBlockSize) < rows:
ySize = yBlockSize
else:
ySize = rows - i
# cycle col blocksize
for j in range(0, cols, xBlockSize):
# set xblocksize
if (j + xBlockSize) < cols:
xSize = xBlockSize
else:
xSize = cols - j
# read block data
data = band.ReadAsArray(j, i, xSize, ySize).astype(np.float)
sumIncludeZero = sumIncludeZero + np.sum(np.sum(data))
mask = np.greater(data, 0)
zeroCount = zeroCount + np.sum(np.sum(mask))
# calculate
avg_includeZero = sumIncludeZero / (rows * cols)
avg_ignoreZero = sumIncludeZero / zeroCount
print('Average include zero: ', avg_includeZero)
print('Average ignore zero: ', avg_ignoreZero)
2)參考答案給的程式碼
# Assignment 4b:Write a script to calculate the average pixel value for the first band in aster.img
#reference answer
import os, sys
# import utils
use_numeric = True
try:
from osgeo import ogr, gdal
from osgeo.gdalconst import *
import numpy
os.chdir('E:/data/GDAL/ospy_data4')
use_numeric = False
except ImportError:
import ogr, gdal
from gdalconst import *
import Numeric
os.chdir('E:/data/GDAL/ospy_data4')
# register all of the GDAL drivers
gdal.AllRegister()
# open the image
ds = gdal.Open('aster.img', GA_ReadOnly)
if ds is None:
print('Could not open aster.img')
sys.exit(1)
# get image size
rows = ds.RasterYSize
cols = ds.RasterXSize
bands = ds.RasterCount
# # get the band and block sizes
# band = ds.GetRasterBand(1)
# blockSizes = utils.GetBlockSize(band)
# xBlockSize = blockSizes[0]
# yBlockSize = blockSizes[1]
band = ds.GetRasterBand(1)
xBlockSize = 20
yBlockSize = 20
# initialize variables
count = 0
total = 0
# loop through the rows
for i in range(0, rows, yBlockSize):
if i + yBlockSize < rows:
numRows = yBlockSize
else:
numRows = rows - i
# loop through the columns
for j in range(0, cols, xBlockSize):
if j + xBlockSize < cols:
numCols = xBlockSize
else:
numCols = cols - j
# read the data and do the calculations
if use_numeric:
data = band.ReadAsArray(j, i, numCols, numRows).astype(Numeric.Float)
mask = Numeric.greater(data, 0)
count = count + Numeric.sum(Numeric.sum(mask))
total = total + Numeric.sum(Numeric.sum(data))
else:
data = band.ReadAsArray(j, i, numCols, numRows).astype(numpy.float)
mask = numpy.greater(data, 0)
count = count + numpy.sum(numpy.sum(mask))
total = total + numpy.sum(numpy.sum(data))
# print results
print('Ignoring 0:', total / count)
print('Including 0:', total / (rows * cols))
資料下載:https://download.csdn.net/download/qq_37935516/10795361