三坐标测量中的最小二乘法和切比雪夫法理论与实践应用

在产品几何量领域中,从两点测量到多点测量,特别三坐标测量机扫描技术不断的进步,蔡司VAST GOLD,VAST XT主动扫描探头在恒测力情况下出色的扫描性能,在探头内部自动调节位置,使探针弯曲参数在任意曲率表面都能表现出一致,从而可以产生超高速的测量体验,也为我们复现工件的原貌提供了更多准确的点,使我们的计算不再基于元素的最少点数。在处理三坐标测量数据时,我们常常需要拟合元素模型来描述测量数据的特征,比如测量了一条直线,实际上的点并不是都在这一条理想的直线上,有可能是离散的分布在直线的两边,那么用一个什么样的直线方程去代表这些点所形成的直线,这就是拟合。拟合:最接近真相的方法。没有办法获取最为准确的解,于是,我们退而求其次,希望能够找到距离结果最近的近似解来解决问题。我们又该如何定义和描述这个“距离最近”呢?这就是拟合算法解决的问题。

现在的拟合算法有:

*   最小二乘法
*   最小区域法
*   最大内切法
*   最小外接法

我们常用的计算几何距离,基准矢量方向的计算方法都是最小二乘法,当然这种说法有可能和标准说法相悖,这也是退而求其次找到最接近真值的方法。比如标准会说对应基准的矢量方向应该用外接或者内切的方法,问题是外切平面位置和方向的计算取决于已测点的精确值。由灰尘,孔洞,碎片等引起的局部形状偏差会导致拟合几何要素的方位产生偏移。把工件放置在平板上后工件自身的重量会将所有的形状偏差“压扁”。但是,为了得到可靠的测量结果,基准必须可以再现。

再举例,比如方向公差:高斯法可以用来评估方向公差,因为此时只有基准的方向是重要的。而对于位置度和圆跳动公差:高斯法不能用来评估位置和圆跳动公差因为此时基准的位置和方向都很重要。可能的解决方案:将高斯平面向材料外部平移50%的形状偏差,而不是用切比雪夫平面。在三坐标测量领域中,标准并不适用于所有情况。

那我们来研究一下最为常见的最小二乘法和上面所说的切比雪夫法(即最小区域法)。以最小二乘圆和最小区域圆为例。最小二乘圆是一种拟合圆形结构的数学模型,其目标是通过最小化数据点到拟合圆的距离的平方和,找到一个最佳的圆形拟合。这种方法对于在噪声较大的数据集中提供鲁棒性拟合非常有用,尤其是当我们试图还原物体表面的圆形特征时。


最小二乘圆用数学公式描述为:

f_i = \sqrt{(x_i-x_G)^2+(y_i-y_G)^2} - r_G
x_G,y_G,r_G : \sum_{i=1}^{n}{f_i^2} \to Min!


这里圆的拟合涉及到的是最小化的问题,对于最小二乘圆,所求的就是残差的平方和最小。当涉及到最小化问题,Python 的 SciPy 库提供了强大的工具和函数。SciPy 是建立在 NumPy基础之上的一个开源科学计算库,它提供了许多高级的数学、信号处理、优化、统计和其他科学计算领域的工具。由于其广泛的应用领域和强大的功能,SciPy已经成为科学计算中不可或缺的一部分。它的模块化结构允许用户选择性地导入所需的功能,从而保证了灵活性和效率。scipy.optimize 模块是 SciPy中的一个关键模块,专注于提供各种优化算法。这个模块不仅仅包含了 minimize 函数,还包括了其他一些常用的优化方法,如最小二乘法、全局优化等。scipy.optimize 的设计旨在满足不同类型优化问题的需求,使得用户能够选择最适合其问题的算法。scipy.optimize.minimize 函数是 scipy.optimize 模块的一个重要组成部分。它为用户提供了一个统一的接口来解决多变量标量函数的最小化问题。通过支持多种优化算法,包括梯度下降、共轭梯度、牛顿法等,该函数能够适应不同类型和规模的问题。

scipy.optimize.minimize 函数用于最小化一个多变量标量函数,以下是其基本用法和接口的概述: 


from scipy.optimize import minimize

# 定义目标函数
def objective(x):
    return x[0]**2 + x[1]**2

# 初始猜测值
initial_guess = [1.0, 1.0]

# 使用 minimize 函数进行最小化
result = minimize(object_function, initial_guess, method='SLSQP')

print("Optimal parameters:", result.x)
print("Minimum value:", result.fun)

在上述示例中,

object_function 是要最小化的目标函数,

initial_guess 是算法的初始猜测值。

method 参数指定了使用的优化算法,这里使用的是 SLSQP 算法。SLSQP(Sequential Least Squares Programming) 是 scipy.optimize.minimize 函数中的一种优化方法,用于处理有约束的非线性优化问题。它通过使用序列最小二乘规划(Sequential Least Squares Programming)方法来寻找目标函数的最小值。还有下面的一些算法,只做简单概述。
'Nelder-Mead'(默认):使用单纯形(simplex)方法,无需计算梯度,处理对于梯度不可用或者代价函数不光滑的问题。
'Powell':Powell方法是一种不需要计算梯度的优化方法,适用于非线性约束的优化问题。适用对于问题有非线性约束,并且梯度难以计算时。
'CG'(共轭梯度):使用共轭梯度法,通常适用于大规模优化问题。对于梯度可用、Hessian 矩阵不必须明确计算的问题适用。
'BFGS'(拟牛顿法):使用拟牛顿法,适用于梯度可用、但 Hessian 矩阵不容易计算的问题。通常在小规模问题中表现良好,相对于共轭梯度法,迭代过程更稳定。
'L-BFGS-B'(有约束的拟牛顿法):基于 BFGS 的优化方法,适用于带有边界约束的问题。在有约束的情况下,特别是有边界约束时。
'TNC':Truncated Newton Conjugate-Gradient 方法,适用于带有约束的优化问题。对于带有线性和非线性约束的问题。
'COBYLA':Constrained Optimization BY Linear Approximations,适用于有约束的优化问题。对于不可微的目标函数或者约束条件时。

```
#! /usr/bin/env python
# -*- coding: utf-8 -*-
'''
@author: ZCJOHNLV
@Version: V1.0
'''

import numpy as np
from scipy.optimize import minimize

# 定义计算圆心和半径的函数
# 圆的方程:(x-a)^2 + (y-b)^2 = r^2
def fit_circle(points):

    # 定义目标函数
    def objective(params):
        a, b, r = params
        return sum((np.sqrt((x - a)**2 + (y - b)**2) - r)**2 for x, y in points)

    # 用中心位置作为圆心初始猜测
    x_m = np.mean([p[0] for p in points])
    y_m = np.mean([p[1] for p in points])
    initial_guess = [x_m, y_m, 1]

    # 最小化目标函数
    result = minimize(cost, initial_guess, method='SLSQP')

    if result.success:
        return result.x  # 返回圆心坐标和半径
    
    else:
        raise ValueError("最小二乘拟合失败")


points = np.loadtxt('./data/circle.txt', usecols=(0, 1))
circle_params = fit_circle(points)
print(f"圆心: ({circle_params[0]:.4f}, {circle_params[1]:.4f}), 直径: {circle_params[2]*2:.4f}")
```

同组数据和ZEISS  CALYPSO对比,圆心位置和直径相差0.0002。

最小区域法(Minimum Zone Circle, MZC)的数学描述为,

f_i = \sqrt{(x_i-x_C)^2+(y_i-y_C)^2} - r_C

x_C,y_C,r_C : \sum_{i=1....n}^{n}{|f_i|} \to Min!

ISO 1101:2017标准将圆度定义为“提取圆周应限定在半径之差为t的两个共面同心圆之间的公差带内”。这意味着,如果一个物体的边界能够在两个半径相差为t的同心圆内变化,那么这个物体的圆度误差就是t。所以最小区域法在定义上就符合对形状度的评定,在现今的坐标测量中这个也被作为形状评定的标准算法。在最小区域法中,我们寻找一个“最小区域圆”,即使得该圆的内、外两个圆的径向距离之差最小,并使得所有数据点都落在这两个圆的包络之内。

```
#! /usr/bin/env python
# -*- coding: utf-8 -*-
'''
@author: ZCJOHNLV
@Version: V1.0
'''

import numpy as np
from scipy.optimize import minimize

def min_area_circles(points):
    # 目标函数:最小化外圆和内圆半径的差距
    def objective(params):
        _, _, r_inner, r_outer = params
        return r_outer - r_inner

    # 约束条件:确保所有点都在两个圆之间
    def constraints(params):
        cx, cy, r_inner, r_outer = params
        cons = []
        for x, y in points:
            d = np.sqrt((x - cx)**2 + (y - cy)**2)
            cons.extend([r_outer - d, d - r_inner])
        return cons

    # 初始猜测
    center_x, center_y = np.mean(points, axis=0)
    r_guess = np.std(points - [center_x, center_y])  # 初始半径猜测
    initial_guess = [center_x, center_y, r_guess, r_guess + 1]

    # 优化
    result = minimize(objective, initial_guess, constraints={'type': 'ineq', 'fun': constraints})

    if result.success:
        return result.x
    else:
        raise ValueError("最小区域法拟合失败")

# 加载点
points = np.loadtxt('./data/circle.txt', usecols=(0, 1))
params = min_area_circles(points)
print(f"圆心: ({params[0]:.4f}, {params[1]:.4f}), 内圆半径: {params[2]:.4f}, 外圆半径: {params[3]:.4f}")
print(f"中心圆圆半径: {(params[2]+params[3]):.4f}")
print(f"圆度: {(params[3]-params[2]):.4f}")

同样和CALYPSO的对比数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值