GDAL+Python實現柵格影像處理之拼接鑲嵌Mosaic

GDAL+Python實現柵格影像處理之鑲嵌

鑲嵌概念

鑲嵌是指將有重疊區域的多個圖像根據其地理座標將其拼接生成一個圖像的過程。
實現原理:

  • 1、計算各個待鑲嵌圖像的四至範圍,然後對計算的各個待鑲嵌的圖像的四至範圍求並得
    到整個鑲嵌結果的四至範圍
  • 2、通過指定輸出圖像的分辨率以及計算的四至範圍計算輸出圖像的大小,並創建輸出圖像
  • 3、循環處理每個待鑲嵌圖像,將待鑲嵌圖像的像元讀取出來並寫入鑲嵌結果圖像中的對應位置
  • 4、處理完所有的待鑲嵌圖像,關閉結果圖像,清理資源等

使用方法

在講述方法之前,列舉一下numpy中的幾個例子,因爲下面我們會使用。

    a=numpy.array([(2,23,4),(23,3,4),(2345,56,8)])
    # 矩陣切片替換 將a矩陣2行 數據替換
    a[1,:]=(56,3,5) 
    b=numpy.array([(54,34,23)])
    # 矩陣增加維度(行數和列數) 在a矩陣下增加其行數
    print(numpy.r_[a,b]
  • 方法1 :通過鑲嵌原理自定義方法實現。由於我的兩幅圖像位置固定,未根據其他情況進行拼接。讀者可以參考這種方式,因爲理解思路最重要。

代碼實現

def RasterMosaic():
    ds=gdal.Open(inputfilePath,gdal.GA_ReadOnly)
    db=gdal.Open(referencefilefilePath,gdal.GA_ReadOnly)
    # todo 判斷兩影像相對位置(計算一副圖像頂點對應在另一幅影像中的行列號)
    Originx = int((ds.GetGeoTransform()[0]-db.GetGeoTransform()[0])/db.GetGeoTransform()[1])
    Originy = int((ds.GetGeoTransform()[3]-db.GetGeoTransform()[3])/db.GetGeoTransform()[5])
    # 第一步判斷頂點是否在其中
    if(Originx<db.RasterXSize and Originy<db.RasterYSize):
        print("頂點在其內")
        # 第二步判斷右下角是否在其內
        OriginRightx=Originx+ds.RasterXSize
        OriginRighty=Originy+ds.RasterYSize
        # 根據兩頂點判斷其上下左右的情況
        if(OriginRightx<db.RasterXSize and OriginRighty<db.RasterYSize):
            print("右下角也在其內")
        elif(OriginRightx<db.RasterXSize and OriginRighty <db.RasterySize):
            print("右下角不在其內且右邊界未超出最大邊界")
            # todo 將兩幅影像公共部分分別都表示出來
            data1 = ds.GetRasterBand(1).ReadAsArray(0, 0, ds.RasterXSize, ds.RasterYSize)[0:db.RasterYSize - Originy,
                    0:ds.RasterXSize]
            data2 = db.GetRasterBand(1).ReadAsArray(0, 0, db.RasterXSize, db.RasterYSize)[
                    Originy:db.RasterYSize - Originy, Originx:Originx + ds.RasterXSize]
            # 表示出在外部的那一部分數據
            dataexcept = ds.GetRasterBand(1).ReadAsArray(0, 0, ds.RasterXSize, ds.RasterYSize)[
                         db.RasterYSize - Originy:ds.RasterYSize, 0:ds.RasterXSize]
            print(ds.RasterYSize - (db.RasterYSize - Originy))
            datacommon = numpy.zeros(shape=(ds.RasterYSize - (db.RasterYSize - Originy), db.RasterYSize), dtype=int)
            datacommon[:, Originx:ds.RasterXSize + Originx] = dataexcept
            data = numpy.r_[db.GetRasterBand(1).ReadAsArray(0, 0, db.RasterXSize, db.RasterYSize), datacommon]
        elif(OriginRightx>db.RasterXSize and OriginRighty<db.RasterYSize):
            print("右下角不在其內且右邊界超出最大邊界並且下邊界未超出最大邊界")
        elif(OriginRightx>db.RasterXSize and OriginRighty>db.RasterYSize):
            print("右下角不在其內且右邊界超出最大邊界並且下邊界未超出最大邊界")
            width=db.RasterYSize
            height=OriginRighty
        outputfilePath = 'G:/studyprojects/gdal/GdalStudy/Files/images/RasterMosaic.tif'
        ds = gdal.Open(inputfilePath, gdal.GA_ReadOnly)
        driver = gdal.GetDriverByName('GTiff')
        output = driver.Create(outputfilePath, Originx+ds.RasterXSize, db.RasterYSize, db.RasterCount, db.GetRasterBand(1).DataType)
        output.SetGeoTransform(db.GetGeoTransform())
        output.SetProjection(db.GetProjection())
        for i in range(db.RasterCount):
            # todo 將兩幅影像公共部分分別都表示出來
            data1 = ds.GetRasterBand(i+1).ReadAsArray(0, 0, ds.RasterXSize, ds.RasterYSize)[0:ds.RasterYSize,
                    0:db.RasterXSize - Originx]
            data2 = db.GetRasterBand(i+1).ReadAsArray(0, 0, db.RasterXSize, db.RasterYSize)[
                    Originy:ds.RasterYSize + Originy, Originx:db.RasterXSize]
            # 表示出在外部的那一部分數據  這裏是我已知我的圖像位置,只寫了一種情況。
            dataexcept = ds.GetRasterBand(i+1).ReadAsArray(0, 0, ds.RasterXSize, ds.RasterYSize)[0:ds.RasterYSize,
                         db.RasterXSize - Originx:ds.RasterXSize]
            datacommon = numpy.zeros(shape=(db.RasterYSize, ds.RasterXSize - (db.RasterXSize - Originx)), dtype=int)
            datacommon[Originy:ds.RasterYSize + Originy, :] = dataexcept
            data = numpy.c_[db.GetRasterBand(i+1).ReadAsArray(0, 0, db.RasterXSize, db.RasterYSize), datacommon]
            output.GetRasterBand(i + 1).WriteArray(data, 0, 0)
            output.GetRasterBand(i + 1).SetNoDataValue(0)  # todo 給各波段設置nodata值
            output.GetRasterBand(i + 1).FlushCache()  # todo 波段統計量
    else:
        print("頂點不在其內")
  • 方法2:方法2採用gdal.Warp()提供的接口進行鑲嵌

代碼實現

def RasterMosaic():
    print("圖像拼接")
    inputrasfile1 = gdal.Open(inputfilePath, gdal.GA_ReadOnly) # 第一幅影像
    inputProj1 = inputrasfile1.GetProjection()
    inputrasfile2 = gdal.Open(referencefilefilePath, gdal.GA_ReadOnly) # 第二幅影像
    inputProj2 = inputrasfile2.GetProjection()
    outputfilePath = 'G:/studyprojects/gdal/GdalStudy/Files/images/RasterMosaic2.tif'
    options=gdal.WarpOptions(srcSRS=inputProj1, dstSRS=inputProj1,format='GTiff',resampleAlg=gdalconst.GRA_Bilinear)
    gdal.Warp(outputfilePath,[inputrasfile1,inputrasfile2],options=options)

效果展示

原始兩幅圖像位置:
在這裏插入圖片描述
新的影像:
在這裏插入圖片描述
如動圖所示:
在這裏插入圖片描述

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