PRC(Rational Polynomial Coefficients )文件是用来存储用于遥感数据几何校正的RPC模型的文件,目前多存储成xml文件。对于遥感数据来说地理坐标的精确度是十分重要的,L1级别的遥感数据是没有经过几何校正的,也可以简单地理解为数据没有地理坐标。因此可以通过数据包内的RPC文件进行数据校正。
RPC参数是有理函多项式函数模型的参数,可以将遥感影像的图像坐标(Line,Sample)即(行号,列号)与其对应的大地坐标(Lat,Long, Height)即(纬度,经度,高程)用比值多项式一一对应起来。RPC的概念得到了很大的关注是因为RPC不仅可以将传感器成像的物理模型隐藏起来,同时可以通过RPC模型校正出几何精度更高的卫星数据。不同数据厂商使用不同的方法生成RPC文件,但目前大多数都采取的非线性最小二乘法(Non linear Least square)。在成像期间,要拟合的数据由物理传感器模型生成。
RPC文件样例,该数据为Airbus Pleiades Neo的样例数据:
<?xml version="1.0"?>
<Dimap_Document version="3.0">
<Metadata_Identification>
<METADATA_FORMAT version="3.0" profile="PNEO_SENSOR">DIMAP</METADATA_FORMAT>
<METADATA_PROFILE>PNEO_SENSOR</METADATA_PROFILE>
<METADATA_SUBPROFILE>RPC</METADATA_SUBPROFILE>
<METADATA_LANGUAGE>en</METADATA_LANGUAGE>
</Metadata_Identification>
<Rational_Function_Model>
<Resource_Reference>
<RESOURCE_TITLE version="2.1">NITF</RESOURCE_TITLE>
<RESOURCE_ID>RPC00B</RESOURCE_ID>
</Resource_Reference>
<Global_RFM>
<RFM_Validity>
<LONG_SCALE>0.09497798415550429</LONG_SCALE>
<LONG_OFF>5.386471928559029</LONG_OFF>
<LAT_SCALE>0.13878415264120036</LAT_SCALE>
<LAT_OFF>43.32305708203754</LAT_OFF>
<HEIGHT_SCALE>3550</HEIGHT_SCALE>
<HEIGHT_OFF>3450</HEIGHT_OFF>
<SAMP_SCALE>5864</SAMP_SCALE>
<SAMP_OFF>5864</SAMP_OFF>
<LINE_SCALE>11716</LINE_SCALE>
<LINE_OFF>11716</LINE_OFF>
<GroundtoImage_Validity_Domain>
<FIRST_LON>5.291493944403524</FIRST_LON>
<FIRST_LAT>43.18427292939634</FIRST_LAT>
<LAST_LON>5.481449912714533</LAST_LON>
<LAST_LAT>43.461841234678744</LAST_LAT>
</GroundtoImage_Validity_Domain>
<ImagetoGround_Validity_Domain>
<FIRST_COL>0</FIRST_COL>
<FIRST_ROW>0</FIRST_ROW>
<LAST_COL>11728</LAST_COL>
<LAST_ROW>23432</LAST_ROW>
</ImagetoGround_Validity_Domain>
</RFM_Validity>
<GroundtoImage_Values>
<SAMP_DEN_COEFF_1>1</SAMP_DEN_COEFF_1>
<SAMP_DEN_COEFF_2>-0.0369559356163</SAMP_DEN_COEFF_2>
<SAMP_DEN_COEFF_3>-0.0426433251759</SAMP_DEN_COEFF_3>
<SAMP_DEN_COEFF_4>0.0411615283486</SAMP_DEN_COEFF_4>
<SAMP_DEN_COEFF_5>-0.029104046665</SAMP_DEN_COEFF_5>
<SAMP_DEN_COEFF_6>-0.0110560101634</SAMP_DEN_COEFF_6>
<SAMP_DEN_COEFF_7>0.00398822248239</SAMP_DEN_COEFF_7>
<SAMP_DEN_COEFF_8>0.0159897753261</SAMP_DEN_COEFF_8>
<SAMP_DEN_COEFF_9>-0.00179057279937</SAMP_DEN_COEFF_9>
<SAMP_DEN_COEFF_10>0.000873825839003</SAMP_DEN_COEFF_10>
<SAMP_DEN_COEFF_11>0.000138521378526</SAMP_DEN_COEFF_11>
<SAMP_DEN_COEFF_12>-5.04879875657e-05</SAMP_DEN_COEFF_12>
<SAMP_DEN_COEFF_13>-0.00012143771886</SAMP_DEN_COEFF_13>
<SAMP_DEN_COEFF_14>6.00760628115e-05</SAMP_DEN_COEFF_14>
<SAMP_DEN_COEFF_15>0.000179311387447</SAMP_DEN_COEFF_15>
<SAMP_DEN_COEFF_16>-6.05751699553e-05</SAMP_DEN_COEFF_16>
<SAMP_DEN_COEFF_17>-4.27188265484e-05</SAMP_DEN_COEFF_17>
<SAMP_DEN_COEFF_18>-5.44454389227e-05</SAMP_DEN_COEFF_18>
<SAMP_DEN_COEFF_19>-7.00704986358e-05</SAMP_DEN_COEFF_19>
<SAMP_DEN_COEFF_20>-6.80555082595e-06</SAMP_DEN_COEFF_20>
<SAMP_NUM_COEFF_1>-0.124404065191</SAMP_NUM_COEFF_1>
<SAMP_NUM_COEFF_2>1.01488172814</SAMP_NUM_COEFF_2>
<SAMP_NUM_COEFF_3>0.003272676039</SAMP_NUM_COEFF_3>
<SAMP_NUM_COEFF_4>-0.131867177056</SAMP_NUM_COEFF_4>
<SAMP_NUM_COEFF_5>-0.0447944212561</SAMP_NUM_COEFF_5>
<SAMP_NUM_COEFF_6>0.0529746085684</SAMP_NUM_COEFF_6>
<SAMP_NUM_COEFF_7>0.00251353609439</SAMP_NUM_COEFF_7>
<SAMP_NUM_COEFF_8>-0.0360884985904</SAMP_NUM_COEFF_8>
<SAMP_NUM_COEFF_9>-0.00130881300594</SAMP_NUM_COEFF_9>
<SAMP_NUM_COEFF_10>-0.00609863668677</SAMP_NUM_COEFF_10>
<SAMP_NUM_COEFF_11>0.00729422629277</SAMP_NUM_COEFF_11>
<SAMP_NUM_COEFF_12>0.0160432790209</SAMP_NUM_COEFF_12>
<SAMP_NUM_COEFF_13>-0.00147014084558</SAMP_NUM_COEFF_13>
<SAMP_NUM_COEFF_14>0.0025488565382</SAMP_NUM_COEFF_14>
<SAMP_NUM_COEFF_15>-0.0293649806449</SAMP_NUM_COEFF_15>
<SAMP_NUM_COEFF_16>-2.1862387282e-05</SAMP_NUM_COEFF_16>
<SAMP_NUM_COEFF_17>-0.000573493597353</SAMP_NUM_COEFF_17>
<SAMP_NUM_COEFF_18>-0.0132154365799</SAMP_NUM_COEFF_18>
<SAMP_NUM_COEFF_19>0.000257004573055</SAMP_NUM_COEFF_19>
<SAMP_NUM_COEFF_20>-0.000145605452733</SAMP_NUM_COEFF_20>
<LINE_DEN_COEFF_1>1</LINE_DEN_COEFF_1>
<LINE_DEN_COEFF_2>-0.00111947764787</LINE_DEN_COEFF_2>
<LINE_DEN_COEFF_3>-0.0234458983405</LINE_DEN_COEFF_3>
<LINE_DEN_COEFF_4>-0.000613189437568</LINE_DEN_COEFF_4>
<LINE_DEN_COEFF_5>6.02546791548e-06</LINE_DEN_COEFF_5>
<LINE_DEN_COEFF_6>2.59634715052e-07</LINE_DEN_COEFF_6>
<LINE_DEN_COEFF_7>2.71747582625e-05</LINE_DEN_COEFF_7>
<LINE_DEN_COEFF_8>-2.865256072e-06</LINE_DEN_COEFF_8>
<LINE_DEN_COEFF_9>0.000568675223685</LINE_DEN_COEFF_9>
<LINE_DEN_COEFF_10>8.99584150383e-07</LINE_DEN_COEFF_10>
<LINE_DEN_COEFF_11>7.38686668257e-09</LINE_DEN_COEFF_11>
<LINE_DEN_COEFF_12>-1.24671066716e-07</LINE_DEN_COEFF_12>
<LINE_DEN_COEFF_13>-5.5462904017e-07</LINE_DEN_COEFF_13>
<LINE_DEN_COEFF_14>-5.42894838946e-09</LINE_DEN_COEFF_14>
<LINE_DEN_COEFF_15>-2.51422524755e-07</LINE_DEN_COEFF_15>
...
<LINE_NUM_COEFF_20>-5.17418132068e-08</LINE_NUM_COEFF_20>
<ERR_BIAS_COL unit="m">5.618360660264443e-09</ERR_BIAS_COL>
<ERR_BIAS_ROW unit="m">1.4346142052090727e-12</ERR_BIAS_ROW>
</GroundtoImage_Values>
<ImagetoGround_Values>
...
</ImagetoGround_Values>
</Global_RFM>
</Rational_Function_Model>
</Dimap_Document>
关键参数解释
名称 | 描述 | 取值范围 | 单位 |
ERR_BIAS | 偏差,图像中所有点的水平轴的均方根偏差误差 | >= 0 | 米 |
ERR_RAND | 随机误差,图像中每个点每水平轴的均方根随机误差 | >= 0 | 米 |
LINE_OFF | 行偏移,相对于图像中心点(标准化平移参数) | >= 0 | 像素 |
SAMPLE_OFF | 列偏移,相对于图像中心点(标准化平移参数) | >= 0 | 像素 |
LAT_OFF | 大地纬度偏移(标准化平移参数) | -90 至 +90 | 度 |
LONG_OFF | 大地经度偏移(标准化平移参数) | -180 至+180 | 度 |
HEIGHT_OFF | 大地高偏移(标准化平移参数) | 不限 | 米 |
LINE_SCALE | 行比例(标准化比例参数) | >= 0 | 像素 |
SAMPLE_SCALE | 列比例(标准化比例参数) | >= 0 | 像素 |
LAT_SCALE | 大地纬度比例(标准化比例参数) | 0 < LAT_SCALE <= 90 | 度 |
LONG_SCALE | 大地经度比例(标准化比例参数) | 0 < LONG_SCALE <= 180 | 度 |
HEIGHT_SCALE | 大地高比例(标准化比例参数) | > 0 | 米 |
LINE_NUM_COEFF(1-20) | 行分子系数,rn方程分子中多项式的20个系数。 | 不限 | |
LINE_DEN_COEFF(1-20) | 行分母系数。rn方程分母中多项式的20个系数。 | 不限 | |
SAMPLE_NUM_COEFF(1-20) | 列分子系数。cn方程分子中多项式的20个系数。 | 不限 | |
SAMPLE_DEN_COEFF(1-20) | 列分母系数。cn方程分子中多项式的20个系数。 | 不限 |
我们在实际的工作中会遇到要进行RPC裁切的问题,这时大家多半就是使用现有的软件进行裁切,那么如果RPC裁切出现了错误,我们很多情况是不知道有没有出错哪里出错了。这就需要进一步的验证计算。
RPC的数学模型 ( STDI-0002 2.1 (16Nov2000)标准)
描述图像坐标和地面坐标之间物理关系的几何传感器模型称为严格成像模型。严格成像模型表达为,通过图像空间使用行(rows)和列(columns)表示 (r, c)以及地理空间的物体表达为纬度,经度,和高度( φ, λ, h)即地理坐标,将二者建立关系。(
)代表归一化的行和列值,(P, L,H)代表归一化的纬度,经度,和高度。归一化的多项式系数(LINE_NUM_COEF_n, LINE_DEN_COEF_n, SAMP_NUM_COEF_n, SAMP_DEN_COEF_n)。这里使用归一化的值是为了减小计算过程中产生的误差,,取值范围在-1~1之间。在行列值,归一化行列值,地理坐标,和归一化地理坐标之间的归一化转换关系如下:
P = (Latitude - LAT_OFF)/ LAT_SCALEL = (Longitude - LONG_OFF)/ LONG_SCALE H = (Height - HEIGHT_OFF)/ HEIGHT_SCALE rn = (Row - LINE_OFF)/ LINE_SCALE cn = (Column - SAMP_OFF)/ SAMP_SCALE
有理多项式方程为:
三次多项式20个系数:
其中系数
表示的是LINE_NUM_COEF_n, LINE_DEN_COEF_n, SAMP_NUM_COEF_n, SAMP_DEN_COEF_n这组系数。图像坐标单位为像素,地理坐标单位经纬度单位为度(小数点形式),高程坐标单位为米,坐标系使用的是WGS-84大地坐标系。在这个有理多项式函数模型中,由光学投影引起的畸变表示为一阶多项式。而像地球曲率、大气折射及镜头畸变等特征,由二阶多项式逼近。高阶部分的其它未知畸变用三阶多项式模拟。
标准化平移参数和标准化比例参数与RPC模型中4个多项式的80个系数共90个参数共同保存在卫星厂家提供给用户的RPC文件中,也是最必要的90个参数。
Airbus Pleiades Neo RPC XML文件
Airbus 的Neo数据RPC文件为XML格式,以RPC_PNEO开头,同时一些读取RPC文件的库可以支持DIM_****.XML形式的数据。值得注意的是Neo数据采用了新的RPC描述信息。如关键词由Direct_Model和Inverse_Model转换为ImagetoGround_Values和GroundtoImage_Values。另一点要注意的是Neo的左上角第一行第一列是从1,1开始的。因此,如果你还在使用一些老的版本的读取库需要查看是否能支持Neo数据。
常用读取RPC的库就是GDAL,但这里推荐一款读取RPC文件的python库,亲测比较好用。这个项目是法国Borelli Center开源的。Borelli中心是一个混合研究单位,汇集了数学、计算机科学和神经科学领域的研究人员,他们积极参与与生物医学领域和产业技术落地的研究。安装简单可以通过pip安装实现,也可以通过源码安装。
pip install rpcm
rpcmhttps://github.com/centreborelli/rpcm.git如果大家不能访问GitHub,我会帮大家搬运过来的,请自行移步我发布的资源。
同时目前国内很多厂商使用的是_rpc.txt 或者.rpc的文件,这里貌似是不支持的,所以我写了一个python的function可以读取.rpc文件,供大家作为参考。
def read_rpc(self, file):
with open(file, "rb") as f:
i = 0
coox=[]
line_num = []
line_den = []
samp_num = []
samp_den = []
for line in f.readlines(): # 打开后逐行读取
if i < 10:
each_line = line.decode().rstrip().split()
# ‘:’分割,存储为list元素
# cooy.append(each_line[0].replace(':', '')) # 保存第一个元素
coox.append(float(each_line[1])) # 保存第二个元素
i = i + 1
elif i >= 10 and i < 30:
each_line = line.decode().rstrip().split()
line_num.append(float(each_line[1]))
i = i + 1
elif i >= 30 and i < 50:
each_line = line.decode().rstrip().split()
line_den.append(float(each_line[1]))
i = i + 1
elif i >= 50 and i < 70:
each_line = line.decode().rstrip().split()
samp_num.append(float(each_line[1]))
i = i + 1
elif i >= 70 and i < 90:
each_line = line.decode().rstrip().split()
samp_den.append(float(each_line[1]))
i = i + 1
self.linOff = coox[0]
self.colOff = coox[1]
self.latOff = coox[2]
self.lonOff = coox[3]
self.altOff = coox[4]
self.linScale = coox[5]
self.colScale = coox[6]
self.latScale = coox[7]
self.lonScale = coox[8]
self.altScale = coox[9]
self.inverseColNum = samp_num
self.inverseColDen = samp_den
self.inverseLinNum = line_num
self.inverseLinDen = line_den
print('Reading RPC Done')