Matlab实现移动曲面拟合法


0 前言

  高程拟合就是根据参考点(已知点)上的高程异常值求出其他待定点上的高程异常值,在数学上属于拟合的问题。作为一种精度较高,计算方法简单,对计算机内存要求低的移动曲面拟合法(Moving Surface Fitting,MSF)常用于由离散数据点计算未知点的高程异常值,但该法计算速度相对于多项式拟合法和多面函数法来讲可能比较慢。

1 理论

  在指定半径为 R R R的范围中,以已知的中心点为圆心并和周围的已知点建立一个拟合曲面,这个曲面在中心点上的内插值即为所求值,关键的是这个有限区域会随着中心点位置的移动而变化,由以上描述可以看出,移动曲面法属于局部逼近法。
  假设某测量点 A ( x , y ) A(x,y) A(x,y)的平面坐标 ( x , y ) (x,y) (x,y)和高程异常 ξ \xi ξ间有如下关系:
ξ = f ( x , y ) + ε \xi =f(x,y)+\varepsilon ξ=f(x,y)+ε
  式中, f ( x , y ) f(x,y) f(x,y)为高程异常的趋势面, ε \varepsilon ε为两者的残差。引入二次曲面的数学模型:
ξ = a 0 + a 1 x + a 2 y + a 3 x 2 + a 4 y 2 + a 5 x y \xi ={{a}_{0}}+{{a}_{1}}x+{{a}_{2}}y+{{a}_{3}}{{x}^{2}}+{{a}_{4}}{{y}^{2}}+{{a}_{5}}xy ξ=a0+a1x+a2y+a3x2+a4y2+a5xy
  设测区内高程异常为的已知点有 n ( n > 6 ) n(n>6) n(n>6)个,那么 a 0 {{a}_{0}} a0 a 5 {{a}_{5}} a5这6个待定系数可运用二次曲面拟合的方法求定。由于各已知点到中心点的距离与这些点在最小二乘计算中所作贡献的大小有关,因此,对高程异常按距离进行加权,利用权函数式:
P ( d i ) = [ ( R − d i ) / d i ] 2 ( i = 1 , 2 , ⋯ n ) P({{d}_{i}})={{[(R-{{d}_{i}})/{{d}_{i}}]}^{2}}(i=1,2,\cdots n) P(di)=[(Rdi)/di]2(i=1,2,n)
  式中, d i = ( x i − x ) 2 + ( y i − y ) 2 {{d}_{i}}=\sqrt{{{({{x}_{i}}-x)}^{2}}+{{({{y}_{i}}-y)}^{2}}} di=(xix)2+(yiy)2 R R R为搜索半径。
  设中心点 A A A周围的点坐标为 ( x i , y i ) ({{x}_{i}},{{y}_{i}}) (xi,yi),其在移动坐标系中的坐标为:
x i A = x i − x y i A = y i − y \begin{align}& x_{i}^{A}={{x}_{i}}-x \\ & y_{i}^{A}={{y}_{i}}-y \\ \end {align} xiA=xixyiA=yiy
  假设参与拟合的点数为 n n n,由(1)、(2)式可列误差方程:

ξ i + v i = a 0 + a i x i A + a 2 y i A + a 3 ( x i A ) 2 + a 4 ( y i A ) 2 + a 5 x i A y i A {{\xi }_{i}}+{{v}_{i}}={{a}_{0}}+{{a}_{i}}x_{i}^{A}+{{a}_{2}}y_{i}^{A}+{{a}_{3}}{{(x_{i}^{A})}^{2}}+{{a}_{4}}{{(y_{i}^{A})}^{2}}+{{a}_{5}}x_{i}^{A}y_{i}^{A} ξi+vi=a0+aixiA+a2yiA+a3(xiA)2+a4(yiA)2+a5xiAyiA
   i i i分别取 1 , 2 , ⋯   , n 1,2,\cdots ,n 1,2,,n;各行的权为 P ( d i ) P({{d}_{i}}) P(di)。表示成总误差方程式即为:
V = B X − L V=BX-L V=BXL
  计算各参与拟合的控制点的权 P ( i ) ( i = 1 , 2 , ⋯ n ) P(i)(i=1,2,\cdots n) P(i)(i=1,2,n)并令
P = [ P ( 1 ) 0 0 0 0 P ( 2 ) 0 0 0 0 ⋱ 0 0 0 0 P ( n ) ] P=\left[ \begin{matrix} P(1) & 0 & 0 & 0 \\ 0 & P(2) & 0 & 0 \\ 0 & 0 & \ddots & 0 \\ 0 & 0 & 0 & P(n) \\ \end{matrix} \right] P= P(1)0000P(2)00000000P(n)
  最后,根据最小二乘原理解带权的极小值问题,求得:

X = ( B T P B ) − 1 B T P L X={{({{B}^{T}}PB)}^{-1}}{{B}^{T}}PL X=(BTPB)1BTPL
  代入可得 ξ i {{\xi }_{i}} ξi
  由以上叙述可以看出,多项式曲面拟合模型和加权平均拟合模型是移动曲面模型的基础,移动曲面模型包含了加权平均的局部适应性强特点及多项式曲面拟合的整体性较好的特点,两种模型的结合还起到抵消部分模型误差的作用,使该模型的适用范围增大、精度提高,因此这是一种有效的GNSS高程拟合方法.

2 实现

2.1 测试数据准备

  首先准备EXCEL数据,这里说明一下,最后一列BOOL中:1代表已知高程异常值点,2代表未知高程异常值点

点号X (/m)Y (/m)Z (/m)BOOL
83566375.346499179.7421.03441
233566854.849498567.50621.00761
103566324.251498659.47421.01721
53563826.318499348.91721.0561
73564312.203500321.49821.08561
113564001.762500035.2721.07891
223567961.396498691.01820.99781
263567524.909500219.01721.05161
43565549.066498813.55821.02851
283568016.26499235.36921.01381
23565858.0849924821.04320
33564029.592499613.37821.06540
63566091.401499632.43421.05540
93564827.161500392.77321.08260
213566814.669499080.19921.02730
13564231.786499937.72321.07440
203567660.247499189.33421.0170

2.2 代码实现部分

%% 文件打开
clear;clc;close all;
[data]=xlsread('MLS.xlsx');%文件位置需要自行更改
%% 数据预处理
KPoint=[];                  %高程异常值已知的点
UPoint=[];                  %高程异常值未知的点
for i=1:size(data,1)
    if data(i,5)==1
        KPoint=[KPoint;data(i,1:4)];
    else
        UPoint=[UPoint;data(i,1:4)];
    end
end
x=KPoint(:,2);              %已知高程异常值点x坐标
y=KPoint(:,3);              %已知高程异常值点y坐标
z=KPoint(:,4);              %已知高程异常值点z坐标
X=UPoint(:,2);              %未知高程异常值点X坐标
Y=UPoint(:,3);              %未知高程异常值点Y坐标
Zz=UPoint(:,4);             %未知高程异常值点Z真值
%% 系数计算
%Z =MSF(x,y,z,X,Y);
%MSF	移动二次曲面插值函数
%x,y	已知高程异常值点坐标x,y
%z      已知高程异常值
%X,Y	未知高程异常值点坐标X,Y
[m0, n0]=size(x);
[m1, n1]=size(Y);
for i=1:m1
    a=m0*n1*(i-1)+1;
    b=m0*n1*(i-1)+m0;
    %生成距离矩阵Dis(m0*m1*n1,n0)
    Dis(a:b,:)=sqrt((X(i)-x).^2+(Y(i)-y).^2);
    if find(Dis(a:b,:)==0)
        [m2,n2]=find(Dis(a:b,:)==0);
        Z(i,1)=z(m2,n2);
    else
        D=Dis(a:b,:);
        dx=sort(D,'descend');%'ascend' 表示升序(默认值),'descend' 表示降序
        R=dx(end-5);         %确定搜索半径选择距离最近的7个点
        [m2,n2]=find(Dis(a:b,:)<=R);
        A=ones(size(m2,1),6);
        A(:,1)=1;
        A(:,2)=x(m2)-X(i);
        A(:,3)=y(m2)-Y(i);
        A(:,4)=(x(m2)-X(i)).*(y(m2)-Y(i));
        A(:,5)=(x(m2)-X(i)).^2;
        A(:,6)=(y(m2)-Y(i)).^2;
        L=z(m2);             %已知高程异常值
        %定权1反距离定权
        Pl=diag(1./D(m2).^2);
        %定权2
        %Pl=diag((((R-D(m2)))./D(m2)).^2);
        %定权3
        %Pl=diag(exp(-(D(m2)./mean(D(m2))).^2));
        %三次样条函数定权
%         for j=1:size(m2,1)
%             sb=abs(x(m2(j))-X(i))/R;
%             if sb<0.5
%                 w(j)=2/3-4*sb^(-2)+4*sb^(-3);
%             elseif sb>1
%                 w(j)=0;
%             else
%                 w(j)=4/3-4*sb+4*sb^(-2)-4/3*sb^(-3);
%             end
%         end
%         Pl=diag(w);
    end
    
    %--计算**最小二乘法**下的曲面系数
    X0=(A'*Pl*A)\(A'*Pl*L);    %同时作为整体最小二乘法的迭代初值
    %X0=lsqminnorm(A'*Pl*A,A'*Pl*L);
    %加入岭参数避免方程病态求解
%     for k=1:10000
%         X1=(A'*Pl*A+(k*6*eye(6)))\(A'*Pl*L);    %同时作为整体最小二乘法的迭代初值
%         if abs(X1(1)-Zz(i,1))<abs(X0(1)-Zz(i,1))
%             X0=X1;
%         end
%     end
    Z(i,1) = X0(1);
end

%% 评价指标计算
V=Z-Zz;          %残差计算(单位mm)
Aver=mean(abs(V));      %误差均值
IP=sqrt(sum(V.^2)/(size(Zz,1)-1));  %内符合精度inner precision
OP=sqrt(sum(V.^2)/(size(z,1)-1));   %外符合精度outer precision

%% 结果输出
Result=[UPoint Z];          %将结果保存再UPoint矩阵中,便于对比

  第5列为由平面位置拟合得到的高程异常值,第4列为该点处高程异常值验证值。

在这里插入图片描述

2.3 进一步获取结果

  根据2.2中的计算结果,我们可以进一步输出得到自己需要的图,这里只展示几种简单的,想要生成更多图形可参靠MATLAB官方支持.

%绘图输出
SResult=sortrows(Result,2); %按照点号排序

ff = figure('Name','结果输出','NumberTitle','off');
set(ff, 'Position',[351,96,1346,832],'color','white')

subplot(221); 
scatter(X,Y,20,[0 0 1],'+'); 
hold on%将拟合点和控制点同时输出在同一张图上
scatter(x,y,20,[1 0 0],'o');
text(x,y,num2str(KPoint(:,1))); %输出控制点点号
text(X,Y,num2str(UPoint(:,1))); %输出拟合点点号
legend('未知点','已知点');
title('坐标点平面位置图');
xlabel('X');
ylabel('Y');

subplot(222); 
plot(SResult(:,2),SResult(:,4),'-*',SResult(:,2),SResult(:,5),'-o');
%横轴为X,与坐标点平面位置图相对应
text(SResult(:,2),SResult(:,4),num2str(SResult(:,1))); %标注点号
legend('拟合前高程异常值(m)','拟合后高程异常值(m)');
title('拟合前后高程异常对比图');
xlabel('X');
ylabel('高程异常值(m)');

subplot(224); 
bar(SResult(:,2),(SResult(:,5)-SResult(:,4))*1000,'group','b');
text(SResult(:,2),(SResult(:,5)-SResult(:,4))*1000,num2str(SResult(:,1))); %标注点号
%横轴为X,与坐标点平面位置图相对应
title('残差直方图');
xlabel('X');
ylabel('残差值(mm)');

在这里插入图片描述


               赶紧点赞、收藏起来吧!不然下次就找不到了💕

  • 15
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

测不绘的返工小渠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值