鑲嵌概念
鑲嵌是指將有重疊區域的多個圖像根據其地理座標將其拼接生成一個圖像的過程。
實現原理:
- 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)
效果展示
原始兩幅圖像位置:
新的影像:
如動圖所示: