利用GDAL實現對兩幅大小不同的柵格影像相交部分作差值計算

利用GDAL實現對兩幅大小不同的柵格影像相交部分作差值計算

項目需求

項目中需要使用對兩幅行列數不同的柵格影像中相交部分做差值計算。
在這裏插入圖片描述

項目構想

  • 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) 

效果展示

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章