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

如何在OpenCV中通过两个端点、半径和圆心绘制圆弧

基于已知圆心、半径、端点用OpenCV绘制彩色分段圆弧

直接调用OpenCV原生ellipse接口即可实现,圆是长短轴相等的特殊椭圆,不需要手动逐点计算圆弧像素,渲染效率和边缘平滑度都有保证。
预期实现效果参考:
彩色分段圆弧效果示意图

实现步骤

  • 计算端点对应圆周角度
    OpenCV绘制圆弧需要传入起始角度、终止角度,角度规则为:以圆心为原点,x轴正方向(向右)为0度,沿顺时针方向角度递增,单位为角度(非弧度)。
    对任意端点(x,y),计算其相对于圆心(cx, cy)的角度公式:
    dx = x - cx
    dy = y - cy
    弧度值 = atan2(dy, dx)
    角度值 = 弧度值 * 180 / π
    
    注意atan2参数顺序:第一个参数传y方向差值,第二个传x方向差值,顺序写反会导致角度计算完全错误。
  • 确定圆弧绘制范围
    两个端点会把整圆切为两段弧,ellipse的绘制逻辑是始终从startAngle顺时针绘制到endAngle,扫过的角度为endAngle - startAngle:
    • 画较短的劣弧时,保证endAngle - startAngle的绝对值小于180即可
    • 画较长的优弧时,可以给终止角度加360,保证扫过的角度大于180
    • 画多段不同颜色的圆弧,只需要依次算出每段弧的起止角度,分别调用ellipse传入对应颜色即可
  • 调用接口绘制
    绘制圆对应的圆弧时,ellipse的椭圆旋转角度参数传0,长短轴参数都传已知半径即可。

代码示例

Python 版本

import cv2
import math
import numpy as np

# 已知参数:圆心坐标、半径、两个圆弧端点
cx, cy = 200, 200
radius = 100
p1 = (300, 200)
p2 = (200, 300)

# 新建空白画布
canvas = np.zeros((400, 400, 3), dtype=np.uint8)

# 角度计算函数
def get_point_angle(pt, center_x, center_y):
    dx = pt[0] - center_x
    dy = pt[1] - center_y
    return math.atan2(dy, dx) * 180 / math.pi

angle1 = get_point_angle(p1, cx, cy)
angle2 = get_point_angle(p2, cx, cy)

# 绘制p1到p2的红色劣弧(90度)
cv2.ellipse(
    canvas,
    center=(cx, cy),
    axes=(radius, radius),
    angle=0,
    startAngle=angle1,
    endAngle=angle2,
    color=(0, 0, 255),  # OpenCV为BGR通道顺序,此处为红色
    thickness=2,
    lineType=cv2.LINE_AA  # 抗锯齿
)

# 绘制剩余的蓝色优弧(270度)
cv2.ellipse(
    canvas,
    center=(cx, cy),
    axes=(radius, radius),
    angle=0,
    startAngle=angle2,
    endAngle=angle1 + 360,
    color=(255, 0, 0),  # 蓝色
    thickness=2,
    lineType=cv2.LINE_AA
)

# 展示结果
cv2.imshow("arc_draw_demo", canvas)
cv2.waitKey(0)
cv2.destroyAllWindows()

C++ 版本

#include <opencv2/opencv.hpp>
#include <cmath>

using namespace cv;

double calcPointAngle(Point2f pt, float cx, float cy) {
    float dx = pt.x - cx;
    float dy = pt.y - cy;
    return atan2(dy, dx) * 180 / CV_PI;
}

int main() {
    // 已知参数
    float cx = 200, cy = 200, r = 100;
    Point2f p1(300, 200), p2(200, 300);
    Mat canvas = Mat::zeros(400, 400, CV_8UC3);

    double a1 = calcPointAngle(p1, cx, cy);
    double a2 = calcPointAngle(p2, cx, cy);

    // 画红色劣弧
    ellipse(canvas, Point(cx, cy), Size(r, r), 0, a1, a2, Scalar(0,0,255), 2, LINE_AA);
    // 画蓝色优弧
    ellipse(canvas, Point(cx, cy), Size(r, r), 0, a2, a1 + 360, Scalar(255,0,0), 2, LINE_AA);

    imshow("arc_draw_demo", canvas);
    waitKey(0);
    return 0;
}

注意事项

  • 不要通过手动计算圆弧散点再连线的方式绘制,原生接口做了亚像素优化,抗锯齿效果更好,运行速度也更快
  • 颜色参数注意OpenCV默认是BGR通道顺序,和常规RGB顺序相反,不要传错
  • 如果绘制的弧和端点没有对齐,优先检查角度计算时dx、dy的顺序和符号,以及角度单位是否误传了弧度
  • 多段彩色圆弧不需要做蒙版或者位运算,按顺序分段绘制即可,后绘制的内容会覆盖在之前的内容上方

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 03:33:31