球面数据拟合算法简介

当我们手中握有大量的数据时,对于二维的数据,我们会对他们进行直线拟合、对数拟合,圆曲线的拟合等等。这些拟合的方法都是运用的了非常古老而又非常有效的方法,即最小二乘法。
今天给大家介绍一种三维球面数据的拟合方法,该方法也是运用的最小二乘的方法。旨在使拟合的半径在均方意义下误差达到最小。

公式推导

设拟合后的球面的球心为(x_0,y_0,z_0)及半径r。
对于每一点拟合后估计的值与实际值的差值为:
1
则误差的平方和为:
2
注意E是x_0,y_0,z_0,r的函数。因此令E分别对x_0,y_0,z_0,r的偏导数等于0,即可求出x_0,y_0,z_0,r,有:
3
令:
4
则有:
5
由(1)-(4)得
6
由(2)-(4)得
7
由(3)-(4)得
8
写成矩阵的形式:
9
求解该矩阵得到x_0,y_0,z_0值,然后带入(4)式中得到r的值。

Matlab仿真

首先生成若干个球面数据,然后加入一定能量的噪声。最后利用上述的公式计算拟合后的球心坐标和球面半径,下面给出的是matlab仿真代码:

%最小二乘的方法进行拟合
clear all;
close all
clc;
R = 2;         %球面半径
x0 = 100;      %球x坐标
y0 = 1;        %球y坐标
z0 = 76;       %球心z坐标
%********************************生成随机球面数据************************************
alfa = 0:pi/50:pi;
sita = 0:pi/50:2*pi;
num_alfa = length(alfa);
num_sita = length(sita);
x = zeros(num_alfa,num_sita);
y = zeros(num_alfa,num_sita);
z = zeros(num_alfa,num_sita);
for i = 1:num_alfa
    for j = 1:num_sita
        x(i,j) = x0+R*sin(alfa(i))*cos(sita(j));
        y(i,j) = y0+R*sin(alfa(i))*sin(sita(j));
        z(i,j) = z0+R*cos(alfa(i));
    end
end

x = reshape(x,num_alfa*num_sita,1);
y = reshape(y,num_alfa*num_sita,1);
z = reshape(z,num_alfa*num_sita,1);
figure;
plot3(x,y,z,'*');
title('生成的没有噪声的球面数据');
%加入均值为0的高斯分布噪声 
amp = 0.1;
x = x + amp*rand(num_alfa*num_sita,1);
y = y + amp*rand(num_alfa*num_sita,1);
z = z + amp*rand(num_alfa*num_sita,1);
figure;
plot3(x,y,z,'*');
title('加入噪声的球面数据');
%*******************************************************************************************
%球面拟合算法
num_points = length(x);
x_avr = sum(x)/num_points;
y_avr = sum(y)/num_points;
z_avr = sum(z)/num_points;

xx_avr = sum(x.*x)/num_points;
yy_avr = sum(y.*y)/num_points;
zz_avr = sum(z.*z)/num_points;
xy_avr = sum(x.*y)/num_points;
xz_avr = sum(x.*z)/num_points;
yz_avr = sum(y.*z)/num_points;

xxx_avr = sum(x.*x.*x)/num_points;
xxy_avr = sum(x.*x.*y)/num_points;
xxz_avr = sum(x.*x.*z)/num_points;
xyy_avr = sum(x.*y.*y)/num_points;
xzz_avr = sum(x.*z.*z)/num_points;
yyy_avr = sum(y.*y.*y)/num_points;
yyz_avr = sum(y.*y.*z)/num_points;
yzz_avr = sum(y.*z.*z)/num_points;
zzz_avr = sum(z.*z.*z)/num_points;
%计算求解线性方程的系数矩阵
A = [xx_avr - x_avr*x_avr,xy_avr - x_avr*y_avr,xz_avr - x_avr*z_avr;
     xy_avr - x_avr*y_avr,yy_avr - y_avr*y_avr,yz_avr - y_avr*z_avr;
     xz_avr - x_avr*z_avr,yz_avr - y_avr*z_avr,zz_avr - z_avr*z_avr];
b = [xxx_avr - x_avr*xx_avr + xyy_avr - x_avr*yy_avr + xzz_avr - x_avr*zz_avr;
     xxy_avr - y_avr*xx_avr + yyy_avr - y_avr*yy_avr + yzz_avr - y_avr*zz_avr;
     xxz_avr - z_avr*xx_avr + yyz_avr - z_avr*yy_avr + zzz_avr - z_avr*zz_avr];
b = b/2;

resoult = inv(A)*b;

x00 = resoult(1);     %拟合出的x坐标
y00 = resoult(2);     %拟合出的y坐标
z00 = resoult(3);     %拟合出的z坐标
r = sqrt(xx_avr-2*x00*x_avr+x00*x00 + yy_avr-2*y00*y_avr+y00*y00 + zz_avr-2*z00*z_avr+z00*z00);   %拟合出的球半径r

运行的结果如下:
10
11
拟合后的x00=100.0502, y00=1.0491, z00=76.0512, r=2.0009与真实的x0=100, y0=1, z0=76, R=2非常的接近。

当然如果得到的球面数据不是在整个球面均匀分布的也可以得到很不错的拟合结果,当得到的数据如下图所示:
12
13
拟合后的x00=100.0510, y00=1.0537, z00=76.0540, r= 1.9952与真实值依然很接近。

  • 18
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
球面拟合算法是一种用于确定一组离散点云数据球面上的最佳拟合球的算法。该算法常被应用于三维重建、三维模型匹配、物体识别等领域。 球面拟合算法的基本思想是找到一个球面,使得该球面上的点到所有离散点的距离之和最小。为了实现这一目标,通常使用最小二乘法进行优化。 具体的球面拟合算法通常包括以下步骤: 1. 初始化:选择一个初始球心和半径作为拟合球的初始估计。 2. 计算距离:计算每个离散点与拟合球的距离。 3. 权重分配:为了更准确地拟合球面,通常会给距离较近的点分配较大的权重。这可以通过高斯加权函数或逆距离加权函数来实现。 4. 参数优化:利用最小二乘法,通过最小化加权距离之和的目标函数来确定最佳拟合球的参数(球心和半径)。 5. 收敛判断:判断优化过程是否收敛,如果没有达到收敛条件,则返回第3步。 6. 输出结果:输出拟合得到的球心和半径,即为最佳拟合球。 需要注意的是,球面拟合算法的结果受到离散点云数据的分布和密度的影响。离散点云数据越密集,拟合结果越精确;反之,数据较稀疏时,拟合结果可能会有一定的误差。 除了最小二乘法,还有其他的球面拟合算法,如RANSAC算法和光线追踪算法等,它们在不同的场景下可能具有更好的适用性。 总之,球面拟合算法是一种通过最小化距离之和来确定一组离散点在球面上的最佳拟合球的算法,具有广泛的实际应用价值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_IRONMAN_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值