項目需求
項目中需要使用對兩幅行列數不同的柵格影像中相交部分做差值計算。
項目構想
- 1、換算出小的影像的座標原點對應的位置在大影像的行列號
- 2、對兩幅二維矩陣進行切片,求出相交區域
- 3、判斷對應相交區域的數值,進行差值計算
項目實現
如圖分析所示
代碼實現
- ReadTheRaster.py
import gdal, gdalconst, numpy
import cv2
import matplotlib.pyplot as plt
class ReadRaster:
def __init__(self, path, ):
self.dataset = gdal.Open(path, gdal.GA_ReadOnly)
self.rows = self.dataset.RasterYSize # todo 圖像寬度
self.cols = self.dataset.RasterXSize # todo 圖像長度
self.bands = self.dataset.RasterCount # TODO 圖像波段數量
self.proj = self.dataset.GetProjection() # todo 地圖投影信息
self.geotrans = self.dataset.GetGeoTransform() # todo 仿射矩陣
def getRasterInformation(self, nband):
band = self.dataset.GetRasterBand(nband) # 獲取波段對象
# data = band.ReadAsArray(0, 0, self.cols, self.rows).astype(numpy.float) #獲取波段信息
data = band.ReadAsArray(0, 0, self.cols, self.rows) # 獲取波段信息
return data
def computedoffset(self):
data = self.geotrans
return data
def computeRows(self):
return self.rows
def computeCols(self):
return self.cols
def writeRasterInformation(self, data, Savepath, nband):
driver = self.dataset.GetDriver()
writeable = driver.Create(Savepath, self.cols, self.rows, self.bands, gdal.GDT_Byte) # TODO 新建數據集
writeable.SetGeoTransform(self.geotrans) # 寫入仿射變換參數
writeable.SetProjection(self.proj) # 寫入投影
for i in range(nband):
writeable.GetRasterBand(i + 1).WriteArray(data[i], 0, 0)
writeable.GetRasterBand(i + 1).SetNoDataValue(0) # todo 給各波段設置nodata值
writeable.GetRasterBand(i + 1).FlushCache() # todo 波段統計量
print(writeable.GetRasterBand(i + 1).GetStatistics(0, 1)) # todo 計算波段統計量 輸出爲min\max \Mean\stddev
return 'success'
- 調用
#TODO RASTERFUNCTION
def computoffset(ds,db): # TODO 計算偏移量從而得出行列號
data1=ds.computedoffset()
data2=db.computedoffset()
xoffset = int((data1[0] - data2[0]) / data1[1])
yoffset = int((data1[3] - data2[3]) / data1[5])
data = [xoffset, yoffset]
return data
def getcludedata(n,ds,db): # TODO 重新切片切成大小相同的
# data = db.getRasterInformation(n)[38:25697, 97:10678] #TODO 調整爲多少行多少列 先化爲相同行相同列 即二維數組切片
data = db.getRasterInformation(n)[computoffset(ds,db)[1]:ds.computeRows()+computoffset(ds,db)[1], computoffset(ds,db)[0]:db.computeCols()] # TODO 調整爲多少行多少列 先化爲相同行相同列 即二維數組切片
return data
def getcludedata2(n,ds,db):
data = ds.getRasterInformation(n)[0:ds.computeRows(),0:db.computeCols()-computoffset(ds,db)[0]]
return data
def getIntersection(n,ds,db):
data1=getcludedata2(n,ds,db)
data2=getcludedata(n,ds,db)
data2[data1==0]=0 # todo 將data1中爲0位置的元素對應把data2中的元素也置爲0
data1[data2==0]=0 # todo 將data2中爲0位置的元素對應把data1中的元素也置爲0
result=abs(data2-data1)
return result
ds = ReadTheRaster.ReadRaster(TheFirstfilepath) #TODO 文件路徑
db = ReadTheRaster.ReadRaster(TheSecondefilepath)
status = ds.writeRasterInformation([getIntersection(1, ds, db), getIntersection(2, ds, db), getIntersection(3, ds, db)],outputfilepath, 3)