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

如何用cv2.ellipse基于两点坐标绘制圆弧?

问题:基于两点坐标绘制肘部圆弧(OpenCV实现)

我有图像中两个点的x、y坐标,想要绘制一条连接这两点的圆弧。目前使用OpenCV的cv2.ellipse函数,但该函数需要起始角度和终止角度,而非点坐标。当前代码如下:

# eclipse 
start_angle = 180 * np.arctan2(coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1])/ np.pi
end_angle = 180 * np.arctan2(coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1])/ np.pi

# Calculate center of the ellipse
center = (coordinates[2][0], coordinates[2][1])

# Draw the ellipse
cv2.ellipse(frame, (int(center[0] * frame.shape[1]), int(center[1] * frame.shape[0])), 
            (100, 100), start_angle, end_angle, 2, (0, 255, 0), -1)  # -1 for filled ellipse

我希望基于两点而非角度绘制圆弧,具体是要绘制表示肘部角度的圆弧(类似肘部关节处的弧形标注)。


解决方案

要实现肘部圆弧标注,核心是围绕肘部中心点,计算上臂、前臂两个方向的角度,再用cv2.ellipse绘制对应弧段,以下是修正后的实现:

关键逻辑

  1. 确定三个核心点:coordinates[1](上臂端点)、coordinates[2](肘部中心)、coordinates[3](前臂端点)
  2. 转换角度体系:OpenCV的角度是顺时针计算(0°对应x轴正方向),而np.arctan2是逆时针角度,需要做转换
  3. 选择正确弧段:判断两个角度的差值,确保绘制的是肘部弯曲内侧的短弧

修正代码

import numpy as np
import cv2

# 假设coordinates为归一化坐标(取值0-1)
vec_upper = np.array([coordinates[1][0] - coordinates[2][0], coordinates[1][1] - coordinates[2][1]])
vec_forearm = np.array([coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1]])

# 将向量转换为OpenCV体系的角度(顺时针0-360°)
def vec_to_opencv_angle(vec):
    rad = np.arctan2(vec[1], vec[0])
    deg = np.degrees(rad)
    return (360 - deg) % 360

angle_upper = vec_to_opencv_angle(vec_upper)
angle_forearm = vec_to_opencv_angle(vec_forearm)

# 确保绘制的是肘部弯曲内侧的短弧
angle_diff = (angle_forearm - angle_upper) % 360
if angle_diff > 180:
    angle_upper, angle_forearm = angle_forearm, angle_upper

# 转换肘部中心为图像像素坐标
center_pixel = (int(coordinates[2][0] * frame.shape[1]), int(coordinates[2][1] * frame.shape[0]))
# 圆弧尺寸,等长轴为圆形弧,可根据需求调整
arc_axes = (60, 60)

# 绘制圆弧(线宽2,绿色;若要填充将最后参数改为-1)
cv2.ellipse(frame, center_pixel, arc_axes, 0, angle_upper, angle_forearm, (0, 255, 0), 2)

替代方案(手动生成圆弧点)

如果不想用cv2.ellipse,可以手动计算圆弧上的采样点,再用cv2.polylines连接:

def get_arc_points(center, radius, start_angle, end_angle, num_points=50):
    # 转换为弧度
    start_rad = np.radians(start_angle)
    end_rad = np.radians(end_angle)
    # 生成角度序列
    angles = np.linspace(start_rad, end_rad, num_points)
    # 计算每个点的坐标
    points = np.array([
        [center[0] + radius * np.cos(angle), center[1] + radius * np.sin(angle)]
        for angle in angles
    ], dtype=np.int32)
    return points.reshape((-1, 1, 2))

# 使用示例
arc_points = get_arc_points(center_pixel, 60, angle_upper, angle_forearm)
cv2.polylines(frame, [arc_points], isClosed=False, color=(0,255,0), thickness=2)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 06:55:40