You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于图像边缘坐标点,求最小二乘平均圆后如何获取最大、最小外接圆直径?

解决方法

一、以最小二乘拟合圆心为中心,覆盖所有点的圆(直径计算)

如果要求圆心固定在你已拟合得到的(xc, yc),步骤如下:

  1. 计算所有边缘点到该圆心的距离:
import numpy as np

# 计算每个点到拟合圆心的欧氏距离
distances = np.sqrt((coordinates[:, 0] - xc)**2 + (coordinates[:, 1] - yc)**2)
  1. 能覆盖所有点的最小圆(圆心固定)的半径等于这些距离的最大值,对应的直径为:
# 覆盖所有点的最小圆半径(圆心固定)
max_radius_fixed = np.max(distances)
# 直径
max_diameter_fixed = 2 * max_radius_fixed

注:若提及“圆心固定的最大圆”,该表述无实际意义——圆可无限放大;若你需要的是所有点到拟合圆心的最小距离对应的圆,直径为2*np.min(distances),但这个圆无法覆盖所有点。

二、全局最小外接圆(覆盖所有点的最小圆,圆心任意)

如果要找不限制圆心位置、能包含所有点的半径最小的圆(即最小外接圆),可通过以下代码实现:

  1. 先安装依赖(未安装时执行):
pip install scipy
  1. 实现代码:
from scipy.spatial import ConvexHull
from scipy.spatial.distance import cdist

def min_enclosing_circle(points):
    # 最小外接圆的顶点必在凸包上,先提取凸包点缩小计算范围
    hull = ConvexHull(points)
    hull_points = points[hull.vertices]
    
    min_radius = float('inf')
    best_center = None

    # 情况1:所有点重合
    if len(hull_points) == 1:
        return hull_points[0], 0.0

    # 情况2:圆由两个点确定(直径为两点间距)
    for i in range(len(hull_points)):
        for j in range(i+1, len(hull_points)):
            p1, p2 = hull_points[i], hull_points[j]
            center = (p1 + p2) / 2
            radius = np.linalg.norm(p1 - p2) / 2
            # 验证所有凸包点是否在圆内(加微小误差 tolerance)
            if np.all(cdist(hull_points, [center]) <= radius + 1e-8):
                if radius < min_radius:
                    min_radius = radius
                    best_center = center

    # 情况3:圆由三个点确定(外接圆)
    for i in range(len(hull_points)):
        for j in range(i+1, len(hull_points)):
            for k in range(j+1, len(hull_points)):
                p1, p2, p3 = hull_points[i], hull_points[j], hull_points[k]
                # 构建线性方程组求解外接圆圆心
                A = np.array([
                    [2*(p2[0]-p1[0]), 2*(p2[1]-p1[1])],
                    [2*(p3[0]-p1[0]), 2*(p3[1]-p1[1])]
                ])
                b = np.array([
                    p2[0]**2 + p2[1]**2 - p1[0]**2 - p1[1]**2,
                    p3[0]**2 + p3[1]**2 - p1[0]**2 - p1[1]**2
                ])
                try:
                    center = np.linalg.solve(A, b)
                except np.linalg.LinAlgError:
                    continue  # 三点共线,跳过该组合
                radius = np.linalg.norm(p1 - center)
                # 验证所有凸包点是否在圆内
                if np.all(cdist(hull_points, [center]) <= radius + 1e-8):
                    if radius < min_radius:
                        min_radius = radius
                        best_center = center

    return best_center, min_radius

# 计算最小外接圆的圆心和半径
min_center, min_radius = min_enclosing_circle(coordinates)
# 最小外接圆直径
min_diameter = 2 * min_radius

关于“最大圆”的补充说明

如果需求是“能覆盖所有点的最大圆”,该表述无实际意义(圆可无限放大)。若你实际需要的是其他相关圆(比如包含所有点的最大内切圆),可补充具体需求后进一步调整实现。

内容的提问来源于stack exchange,提问作者mehmet_kacmaz_03

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 00:12:22