最近在做基于rpc的像方改正模型,友善對資料進行測試,修改了gdal庫中的rpc糾正模型,使之可以支援rpc像方改正參數。
下面是rpc模型的公式,rn,cn為歸一化之後的圖像行列号坐标,plh為歸一化後的經度緯度高程。
将上面的公式變形,使用偏移系數和縮放系數帶入,可以得到圖像的行列号坐标與經緯度坐标之間的坐标轉換關系。整理後的公式如下所示,下标帶s的為縮放系數,下标為0的表示偏移系數,rc為圖像行列号,此處的plh為地面經緯度坐标,p1~p4為有理函數的多項式系數。
使用像方改正模型的公式如下所示,line和sample為圖像的行列号,rc為通過rpc模型将地面點經緯度高程計算得到的行列号,deltar和deltac為像方改正數。
deltar和deltac像方改正數使用仿射變換模型,具體公式如下,a0~a2為行方向的改正系數,b0~b2為列方向改正系數。無改正時這六個系數均為0.
将上面兩個公式合并之後,再将deltar和deltac移向等式坐标,合并同類項之後,就得到了最終的一個仿射變換系數,此時無改正時,六個系數變為0 1 0 0 0 1。該系數為下面是用的最終系數。
修改的代碼很少,在gdal源碼中的alg檔案夾裡面的gdal_rpc.cpp中,具體修改三處地方。
第一處,gdalrpctransforminfo結構體,在結構體中增加兩個double [6]的數組,用于儲存rpc像方改正系數。修改後的代碼如下,最後兩個參數adfaffinetransform和adfreverseaffinetransform分别表示rpc像方改正系數及其逆變換系數。
第二處,在函數gdalcreaterpctransformer()中,主要是将參數papszoptions中的像方改正系數進行解析,然後給結構體中新加的兩個數組指派。便于後續進行坐标轉換的時候使用。修改後的代碼如下,由于代碼太長,隻貼出我修改的部分代碼。下面代碼中the affine transform parameters部分的代碼由我新加,主要是通過一個rpc_affine來指定像方改正的六個系數,六個系數中間用空格隔開。然後将解析後的六個系數計算逆變換系數。預設系數是0 1 0 0 0 1,表示不進行像方改正。
第三處修改的地方就是在進行坐标轉換的函數中,即函數gdalrpctransform()中,這裡面主要修改兩部分,第一個部分就是坐标正變換的時候,第二個是坐标逆變換的時候,在坐标正變換的時候,也就是從經緯度坐标換算到原始圖像行列号坐标時,等使用rpc模型轉換完成後,再使用仿射變換的逆變換系數進行改正;在坐标逆變換的時候,也就是從原始圖像行列号換算到經緯度坐标時,先使用仿射變換的正變換系數進行改正,然後将改正後的行列号帶入rpc模型進行轉換到經緯度。修改的代碼就兩行,但是原始的代碼太多,就貼出來我新增的部分。
修改完之後,儲存,然後重新編譯gdal庫即可。之後我們就可以使用gdalwarp.exe這個超牛的工具來進行校正了。具體的指令就是在原來使用-rpc的指令基礎上,增加一個-to “rpc_affine=0 1 0 0 0 1”即可。當然這六個系數需要自己寫程式使用控制點來進行反算,隻要三個控制點即可,使用1個或兩個控制點隻能計算一個平移模型,即上面公式中的a0和b0。完整的指令行為: