切比雪夫(最小区域法)球拟合算法

欢迎关注更多精彩
关注我,学习常用算法与数据结构,一题多解,降维打击。

本期话题:切比雪夫(最小区域法)球拟合算法

相关背景和理论
点击前往
主要介绍了应用背景和如何转化成线性规划问题

在这里插入图片描述

球拟合输入和输出要求

输入

  1. 10到631个点,全部采样自球附近上。
  2. 每个点3个坐标,坐标精确到小数点后面20位。
  3. 坐标单位是mm, 范围[-500mm, 500mm]。

输出

  1. 1点X0表示 球心,用三个坐标表示。
  2. 球半径r。
  3. 球度F,所有点到球面距离最大的2倍。

精度要求

  1. C点到标准球心距离不能超过0.0001mm。
  2. r与标准半径的差不能超过0.0001mm。
  3. F与标准球度误差不能超过0.00001mm。

球优化标函数

根据论文,球拟合转化成数学表示如下:

球参数化表示

  1. 球心为1点X0 = (x0, y0, z0)。
  2. 半径r。

球方程 ( x − x 0 ) 2 + ( y − y 0 ) 2 + ( z − z 0 ) 2 = r 2 球方程 (x-x_0)^2+(y-y_0)^2+(z-z_0)^2=r^2 球方程(xx0)2+(yy0)2+(zz0)2=r2

点到球距离

第i个点 pi(xi, yi, zi)。

根据点乘得到距离

d i = ∥ ( p i − X 0 ) ∥ − r d_i =\left \| (p_i-X_0) \right \|-r di=(piX0)r

展开一下:

d i = r i − r d_i = r_i -r di=rir

r i = ( x i − x 0 ) 2 + ( y i − y 0 ) 2 + ( z i − z 0 ) 2 r_i = \sqrt{(x_i-x_0)^2 + (y_i-y_0)^2+(z_i-z_0)^2} ri=(xix0)2+(yiy0)2+(ziz0)2

优化能量方程

能量方程 H = f ( X 0 , r ) = max ⁡ 1 n ∣ d i ∣ H=f(X0, r)=\displaystyle \max_1^n {|d_i|} H=f(X0,r)=1maxndi

上式是一个4函数,X0, r是未知量,拟合球的过程也可以理解为优化X0, r使得方程H最小。

转化为线性规划

设 a = ( x 0 , y 0 , z 0 , r ) , d i = F ( x i ;   a ) , 引入 Γ = M A X i = 1 n    ∣ d i ∣ 设a=(x_0, y_0, z_0, r), d_i=F(x_i;\ a), 引入\Gamma=\overset n{\underset {i=1}{MAX}}\;|d_i| a=(x0,y0,z0,r),di=F(xi; a),引入Γi=1MAXndi

根据上述定义,可以将原来的最值问题转化为下述条件

对于所有点应该满足

F ( x i ;   a ) ≤ Γ , ( F ( x i ;   a ) > 0 ) F(x_i;\ a)\le \Gamma, (F(x_i;\ a)>0) F(xi; a)Γ,(F(xi; a)>0)

− F ( x i ;   a ) ≤ Γ , ( F ( x i ;   a ) < 0 ) -F(x_i;\ a)\le \Gamma, (F(x_i;\ a)<0) F(xi; a)Γ,(F(xi; a)<0)

我们可以通过小量迭代慢慢减小Γ

m a x      Δ Γ s . t .     F ( x i , a ) + J Δ a ≤ Γ − Δ Γ , ( i = 1 , 2... n )           − ( F ( x i , a ) + J Δ a ) ≤ Γ − Δ Γ , ( i = 1 , 2... n ) Δ Γ ≥ 0 \begin {array}{c}max \ \ \ \ \Delta {\Gamma}\\ s.t.\ \ \ F(x_i, a) + J\Delta a \le \Gamma -\Delta \Gamma, (i=1,2...n)\\ \ \ \ \ \ \ \ \ \ -(F(x_i, a) + J\Delta a) \le \Gamma -\Delta \Gamma, (i=1,2...n)\\ \Delta \Gamma \ge0\end{array} max    ΔΓs.t.   F(xi,a)+JΔaΓΔΓ,(i=1,2...n)         (F(xi,a)+JΔa)ΓΔΓ,(i=1,2...n)ΔΓ0

上述条件不需要管 F ( x i , a ) + J Δ a 正负情况,若 F ( x i , a ) + J Δ a 为正 − ( F ( x i , a ) + J Δ a ) ≤ Γ − Δ Γ 必成立,反之亦然。 上述条件不需要管F(x_i, a) + J\Delta a正负情况,若F(x_i, a) + J\Delta a为正-(F(x_i, a) + J\Delta a) \le \Gamma -\Delta \Gamma必成立,反之亦然。 上述条件不需要管F(xi,a)+JΔa正负情况,若F(xi,a)+JΔa为正(F(xi,a)+JΔa)ΓΔΓ必成立,反之亦然。
求解出以后更新a, Γ。

对线性规划模型标准化

需要对 Δ x 0 , Δ y 0 , Δ z 0 , Δ r 拆解,要求变量都要大于等于 0 需要对\Delta x_0, \Delta y_0, \Delta z_0, \Delta r 拆解,要求变量都要大于等于0 需要对Δx0,Δy0,Δz0,Δr拆解,要求变量都要大于等于0

m a x      Δ Γ s . t .     J i ⋅ [ Δ x 0 + - Δ x 0 - Δ y 0 + - Δ y 0 - Δ z 0 + - Δ z 0 - Δ r + − Δ r − ] + Δ Γ ≤ Γ - d i , ( i = 1 , 2... n )        − J i ⋅ [ Δ x 0 + - Δ x 0 - Δ y 0 + - Δ y 0 - Δ z 0 + - Δ z 0 - Δ r + − Δ r − ] + Δ Γ ≤ Γ + d i , ( i = 1 , 2... n ) Δ x 0 + , Δ x 0 − , Δ y 0 + , Δ y 0 − , Δ z 0 + , Δ z 0 - , Δ r , Δ Γ ≥ 0 ( 1 ) \begin {array}{c}max \ \ \ \ \Delta {\Gamma}\\ s.t.\ \ \ J_i \cdot \begin {bmatrix} \Delta x_0^+-\Delta x_0^-\\ \Delta y_0^+-\Delta y_0^-\\\Delta z_0^+-\Delta z_0^-\\ \Delta r^+- \Delta r^- \end{bmatrix} +\Delta \Gamma\le \Gamma-d_i, (i=1,2...n)\\\\ \ \ \ \ \ \ -J_i \cdot \begin {bmatrix} \Delta x_0^+-\Delta x_0^-\\ \Delta y_0^+-\Delta y_0^-\\\Delta z_0^+-\Delta z_0^-\\ \Delta r^+- \Delta r^- \end{bmatrix}+\Delta \Gamma\le \Gamma+d_i, (i=1,2...n)\\ \Delta x_0^+, \Delta x_0^-, \Delta y_0^+, \Delta y_0^-, \Delta z_0^+,\Delta z_0^-,\Delta r, \Delta \Gamma \ge0\end{array} (1) max    ΔΓs.t.   Ji Δx0+Δx0Δy0+Δy0Δz0+Δz0Δr+Δr +ΔΓΓdi,(i=1,2...n)      Ji Δx0+Δx0Δy0+Δy0Δz0+Δz0Δr+Δr +ΔΓΓ+di,(i=1,2...n)Δx0+,Δx0,Δy0+,Δy0,Δz0+,Δz0,Δr,ΔΓ0(1)

算法描述

Ji, di的计算。

对4个未知数求导结果如下:

∂ d i ∂ x 0 = 1 2 ( x i − x 0 ) 2 + ( y i − y 0 ) 2 + ( z i − z 0 ) 2 ⋅ ( x i − x 0 ) ⋅ − 1 = − ( x i − x 0 ) / r i \frac {\partial d_i} {\partial x_0}=\frac {1} {2 \sqrt{(x_i-x_0)^2 + (y_i-y_0)^2+(z_i-z_0)^2}}\cdot(x_i-x_0)\cdot -1 = -(x_i-x_0)/r_i x0di=2(xix0)2+(yiy0)2+(ziz0)2 1(xix0)1=(xix0)/ri

∂ d i ∂ y 0 = 1 2 ( x i − x 0 ) 2 + ( y i − y 0 ) 2 + ( z i − z 0 ) 2 ⋅ ( y i − y 0 ) ⋅ − 1 = − ( y i − y 0 ) / r i \frac {\partial d_i} {\partial y_0}=\frac {1} {2 \sqrt{(x_i-x_0)^2 + (y_i-y_0)^2+(z_i-z_0)^2}}\cdot(y_i-y_0)\cdot -1 = -(y_i-y_0)/r_i y0di=2(xix0)2+(yiy0)2+(ziz0)2 1(yiy0)1=(yiy0)/ri

∂ d i ∂ z 0 = 1 2 ( x i − x 0 ) 2 + ( y i − y 0 ) 2 + ( z i − z 0 ) 2 ⋅ ( z i − z 0 ) ⋅ − 1 = − ( z i − z 0 ) / r i \frac {\partial d_i} {\partial z_0}=\frac {1} {2 \sqrt{(x_i-x_0)^2 + (y_i-y_0)^2+(z_i-z_0)^2}}\cdot(z_i-z_0)\cdot -1 = -(z_i-z_0)/r_i z0di=2(xix0)2+(yiy0)2+(ziz0)2 1(ziz0)1=(ziz0)/ri

∂ d i ∂ r = − 1 \frac {\partial d_i} {\partial r}=-1 rdi=1

一次迭代过程

  1. 确定球初值,Γ,使用高斯拟合点击前往

  2. 根据上述公式(1)构建线性规划方程

  3. 求解 Δ p \Delta p Δp

  4. 更新解
    x 0 = x 0 + p x 0 y 0 = y 0 + p y 0 z 0 = z 0 + p z 0 r = r + p r Γ = Γ − Δ Γ \begin {array}{c} x_0 = x_0+p_{x_0} \\y_0 = y_0+p_{y_0} \\z_0 = z_0+p_{z_0} \\ r=r+p_r \\ \Gamma = \Gamma-\Delta \Gamma \end {array} x0=x0+px0y0=y0+py0z0=z0+pz0r=r+prΓ=ΓΔΓ

  5. 重复2直到收敛

最后,输出时F=2*Γ

代码实现

代码链接:https://gitcode.com/chenbb1989/3DAlgorithm/blob/master/CBB3DAlgorithm/Fitting/chebyshev/SphereFitter.cpp

拟合代码

#include "SphereFitter.h"
#include "../gauss/SphereFitter.h"
#include <algorithm>
#include <Eigen/Dense>


namespace Chebyshev {
	double SphereFitter::F(Fitting::Sphere sphere, const Point& p)
	{
		auto de = p - sphere.center;
		return de.norm() - sphere.r;
	}

	double SphereFitter::GetError(Fitting::Sphere sphere, const std::vector<Eigen::Vector3d>& points)
	{
		double err = 0;
		for (auto& p : points) {
			err = std::max(err, abs(F(sphere, p)));
		}

		return err;
	}

	Fitting::Matrix SphereFitter::Jacobi(const std::vector<Eigen::Vector3d>& points)
	{
		Fitting::Matrix J(points.size(), 4);
		for (int i = 0; i < points.size(); ++i) {
			auto  p =  points[i] - sphere.center;
			J(i, 0) = -p.x() / p.norm();
			J(i, 1) = -p.y() / p.norm();
			J(i, 2) = -p.z() / p.norm();
			J(i, 3) = -1;
		}
		return J;
	}

	void SphereFitter::beforHook(const std::vector<Eigen::Vector3d>& points)
	{}

	void SphereFitter::afterHook(const Eigen::VectorXd& xp)
	{
		sphere.center += Eigen::Vector3d(xp(0), xp(1), xp(2));
		sphere.r += xp(3);
		gamma -= xp(4);
	}
	Eigen::VectorXd SphereFitter::getDArray(const std::vector<Eigen::Vector3d>& points)
	{
		Eigen::VectorXd D(points.size());
		for (int i = 0; i < points.size(); ++i)D(i) = F(sphere, points[i]);
		return D;
	}
	bool SphereFitter::GetInitFit(const std::vector<Eigen::Vector3d>& points)
	{
		if (points.size() < 4)return false;
		Fitting::FittingBase* fb = new Gauss::SphereFitter();
		fb->Fitting(points, &sphere);
		delete fb;

		gamma = GetError(sphere, points);
		return true;
	}
	double SphereFitter::F(const Eigen::Vector3d& p)
	{
		return Chebyshev::SphereFitter::F(sphere, p);
	}
	double SphereFitter::GetError(const std::vector<Eigen::Vector3d>& points)
	{
		return Chebyshev::SphereFitter::GetError(sphere, points);
	}
	void SphereFitter::Copy(void* ele)
	{
		memcpy(ele, &sphere, sizeof(Fitting::Sphere));
	}
	SphereFitter::SphereFitter()
	{
		ft = Fitting::FittingType::CHEBYSHEV;
	}
}

测试结果

https://gitcode.com/chenbb1989/3DAlgorithm/blob/master/CBB3DAlgorithm/Fitting/chebyshev/chebyshev-testdata/officialtest/fitting_result/result.txt

C27 : SPHERE : pass
C28 : SPHERE : pass
C29 : SPHERE : pass
C30 : SPHERE : pass
C31 : SPHERE : pass
C32 : SPHERE : pass
C33 : SPHERE : pass
C34 : SPHERE : pass
C35 : SPHERE : pass
C36 : SPHERE : pass

本人码农,希望通过自己的分享,让大家更容易学懂计算机知识。创作不易,帮忙点击公众号的链接。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/412711.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Python笔记-设计模式】命令模式

一、说明 命令模式是一种行为设计模式&#xff0c;旨在对命令的封装&#xff0c;根据不同的请求将方法参数化、延迟请求执行或将其放入队列中&#xff0c;且能实现可撤销操作。 (一) 解决问题 将请求发送者和接受者解耦&#xff0c;请求发送者只需知道如何发送请求&#xff…

【力扣hot100】刷题笔记Day14

前言 又是新的一周&#xff0c;快乐的周一&#xff0c;快乐地刷题&#xff0c;今天把链表搞完再干活&#xff01; 114. 二叉树展开为链表 - 力扣&#xff08;LeetCode&#xff09; 前序遍历 class Solution:def flatten(self, root: Optional[TreeNode]) -> None:if not r…

Ubontu更换软件包源库来提高下载速度

对于 apt-get update 运行缓慢的问题&#xff0c;您可以尝试更换软件包源库来提高下载速度。在 Debian 系统中&#xff0c;可以通过编辑 /etc/apt/sources.list 文件来更改软件包源 1、打开 /etc/apt/sources.list 文件&#xff1a;使用文本编辑器&#xff08;例如 vi、nano 或…

Linux使用Docker部署Traefik容器并实现远程访问管理界面

文章目录 一、Zotero安装教程二、群晖NAS WebDAV设置三、Zotero设置四、使用公网地址同步Zotero文献库五、使用永久固定公网地址同步Zotero文献库 Zotero 是一款全能型 文献管理器,可以 存储、管理和引用文献&#xff0c;不但免费&#xff0c;功能还很强大实用。 ​ Zotero 支…

React Hooks概述及常用的React Hooks介绍

Hook可以让你在不编写class的情况下使用state以及其他React特性 useState ● useState就是一个Hook ● 通过在函数组件里调用它来给组件添加一些内部state,React会在重复渲染时保留这个state 纯函数组件没有状态&#xff0c;useState()用于设置和使用组件的状态属性。语法如下…

StarRocks之监控管理(内含DashBoard模板)

先看下最终效果图 架构 Prometheus 是一个拥有多维度数据模型的、灵活的查询语句的时序数据库。它可以通过 Pull 或 Push 采集被监控系统的监控项,存入自身的时序数据库中。并且通过丰富的多维数据查询语言,满足用户的不同需求。 Grafana 是一个开源的 Metric 分析及可视化系…

springboot-基础-添加model和controller的简单例子+常用注解含义

备份笔记。所有代码都是2019年测试通过的&#xff0c;如有问题请自行搜索解决&#xff01; 上一篇&#xff1a;springboot-基础-eclipse配置helloword示例 目录 添加model和controller的例子注解开发使用RestController 大坑 添加model和controller的例子 文件结构&#xff1…

Vue.js+SpringBoot开发快递管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 数据中心模块2.2 快递类型模块2.3 快递区域模块2.4 快递货架模块2.5 快递档案模块 三、界面展示3.1 登录注册3.2 快递类型3.3 快递区域3.4 快递货架3.5 快递档案3.6 系统基础模块 四、免责说明 一、摘要 1.1 项目介绍 …

(AtCoder Beginner Contest 340) -- F - S = 1 -- 题解

目录 F - S 1&#xff1a; 题目大意&#xff1a; 思路解析&#xff1a; 代码实现&#xff1a; F - S 1&#xff1a; 题目大意&#xff1a; 思路解析&#xff1a; 这道题需要解决的就是三角形面积怎么用 A、B、X、Y&#xff0c;表示。 exgcd求解大致思路&#xff1a;可看C…

时间序列分析实战(四):Holt-Winters建模及预测

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…

ETH网络中的账户

ETH网络中的账户 Externally owned accounts (EOA) - 外部账户 由用户控制&#xff0c;我们导入助记词创建的账户就属于此类账户。 Contract accounts (smart contracts) - 合约账户 合约账户由以太坊虚拟机执行的代码控制。它也被称为智能合约。合约帐户有相关的代码和数据存…

闪测影像|闪测仪,一键自动批量测量尺寸

在现代化工业中&#xff0c;闪测仪只需一键即可快速批量测量尺寸&#xff0c;为产品尺寸控制和质量管理提供重要保障。 工作原理 机器视觉系统的优势是高精度、重复性的进行运作&#xff0c;并能提供清晰的图像。整个系统由光源、镜头、相机、图像采集卡、图像处理软件等组件…

EfficientSAM | 借助MIM机制,MetaAI让SAM更高效!

本文首发&#xff1a;AIWalker 本文介绍了一种名为EfficientSAM的模型&#xff0c;该模型通过利用遮罩图像预训练来提高图像分割的性能。作者使用了一个名为SAMI的方法&#xff0c;通过将SAM图像编码器的特征作为重建目标&#xff0c;从SAM图像编码器中重建特征&#xff0c;从而…

【XR806开发板试用】XR806简单使用GPIO命令通过继电器远程控制其它开发板

一直关注极术社区&#xff0c;参加过社区的好几个活动&#xff0c;这次在微信群得知有开发板使用活动&#xff0c;果断申请试用。一来想借此学习了解鸿蒙系统&#xff0c;再者学习工作中也确实会用到一些小工具。 之前因工作中因自动化测试需要和远程控制测试板子需要(重启板…

Ansible group模块 该模块主要用于添加或删除组。

目录 创建组验证删除组验证删除一个不存在的组 常用的选项如下&#xff1a; gid  #设置组的GID号 name  #指定组的名称 state  #指定组的状态&#xff0c;默认为创建&#xff0c;设置值为absent为删除 system  #设置值为yes&#xff0c;表示创建为系统组 创建组 ansib…

32. 【Linux教程】Linux 修改用户

前面小节介绍了如何添加 Linux 系统用户、删除 Linux 系统用户&#xff0c;本小节介绍如何修改 Linux 系统用户相关的信息。 1. 用户修改相关命令 下面列举了一些修改用户信息相关的命令&#xff1a; 命令名称功能与作用描述usermod修改用户的字段值&#xff0c;并且可以指定…

同源不同页面之间的通信,SharedWorker使用

同源不同页面之间的通信&#xff0c;SharedWorker使用 描述实现结果 描述 同源不同页面之间的通信&#xff0c;使用SharedWorker&#xff0c;或者使用全局方法通信&#xff0c;这里使用SharedWorker来实现 mdn地址&#xff1a;https://developer.mozilla.org/zh-CN/docs/Web/A…

谷歌Gemini又陷舆论风波;AI虚拟女友恋爱指南;高效提示词必学的两个新语法;LLM超超超长资源清单 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f251; 谷歌 Gemini 每次发布大模型必曝「丑闻」&#xff1a;高标准严要求&#xff1f;还是…… https://www.marketwatch.com/story/google-…

机器学习和可视化还能一起这样用?Python教你全搞定

今天这篇推文&#xff0c;我们继续空间数据可视化的最后一个系列-类别插值(categorical-spatial-interpolation) 可视化绘制的推文教程&#xff0c;这期我们使用Python进行绘制&#xff0c;涉及的知识点如下&#xff1a; sklearn.KNeighborsClassifier()机器学习应用 plotnine…

人机界面和三菱PLC之间以太网通信

本文主要描述人机界面WinCC如何与三菱Q系列PLC进行以太网通讯&#xff0c;主要介绍了CPU自带以太网口和扩展以太网模块两种情况以及分别使用TCP、UDP两种协议进行通讯组态步骤及其注意事项。 一、 说明 WinCC从V7.0 SP2版本开始增加了三菱以太网驱动程序&#xff0c;支持和三…