根据一组点的坐标拟合空间平面,有两种方法
第一种:如果在测量得到的数据中,x,y值都是确认没有误差的,而误差只是出现在z值上,则可以使用线性回归的方法,此方法最小二乘的目标是在z方向上de残差
Matlab 代码- % 随机生成一组(x,y,z),这些点的坐标离一个空间平面比较近
- x0=1,L1=2;
- y0=1,L2=2;
- x=x0+rand(20,1)*L1;
- y=y0+rand(20,1)*L2;
- z=1+2*x+3*y;
- scatter3(x,y,z,'filled')
- hold on;
- X = [ones(length(x),1) x y];
- % 拟合,其实是线性回归,但可以用来拟合平面
- % 输出为 b = [b(1) b(2) b(3)] 表示 z = b(1) + b(2)*x + b(3)*y 是拟合出来的平面的方程
- [b,bint,r,rint,stats] = regress(z,X,95);
- % 图形绘制
- xfit = min(x):0.1:max(x);
- yfit = min(y):0.1:max(y);
- [XFIT,YFIT]= meshgrid (xfit,yfit);
- ZFIT = b(1) + b(2) * XFIT + b(3) * YFIT;
- mesh(XFIT,YFIT,ZFIT);
复制代码 输出结果如图1
第二中: 如果在测量得到的数据中,x,y,z都存在误差,则最小化的目标应该是测量点到平面距离的残差
Matlab代码- % 随机生成一组(x,y,z),这些点的坐标离一个空间平面比较近
- x0=1,L1=2;
- y0=1,L2=2;
- x=x0+rand(20,1)*L1;
- y=y0+rand(20,1)*L2;
- z=1+2*x+3*y;
- scatter3(x,y,z,'filled')
- hold on;
- planeData=[x,y,z];
- % 协方差矩阵的SVD变换中,最小奇异值对应的奇异向量就是平面的方向
- xyz0=mean(planeData,1);
- centeredPlane=bsxfun(@minus,planeData,xyz0);
- [U,S,V]=svd(centeredPlane);
- a=V(1,3);
- b=V(2,3);
- c=V(3,3);
- d=-dot([a b c],xyz0);
- % 图形绘制
- xfit = min(x):0.1:max(x);
- yfit = min(y):0.1:max(y);
- [XFIT,YFIT]= meshgrid (xfit,yfit);
- ZFIT = -(d + a * XFIT + b * YFIT)/c;
- mesh(XFIT,YFIT,ZFIT);
复制代码 输出结果如图2
而根据空间点拟合一条空间直线的思路比较直接,就是最小化这些点到直线的距离- % 随机生成一组点,这写点距离直线l比较近,l的过点[1,1,1],方向向量为[1,2,3]
- lineData=bsxfun(@plus, [1,1,1], (-1:.1:1).'*[1,2,3]);
- Noise=rand(size(lineData))*.1;
- lineData=lineData+Noise;
- scatter3(lineData(:,1), lineData(:,2), lineData(:,3),'filled')
- hold on;
- % 拟合的直线必过所有坐标的算数平均值
- xyz0=mean(lineData,1),
- % 协方差矩阵奇异变换,与拟合平面不同的是
- % 所得直线的方向实际上与最大奇异值对应的奇异向量相同
- centeredLine=bsxfun(@minus,lineData,xyz0);
- [U,S,V]=svd(centeredLine);
- direction=V(:,1);
- % 画图
- t=-8:0.1:8;
- xx=xyz0(1)+direction(1)*t;
- yy=xyz0(2)+direction(2)*t;
- zz=xyz0(3)+direction(3)*t;
- plot3(xx,yy,zz)
复制代码 输出结果如图3
|