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

基于单固定半径圆形靶标的OpenCV Python相机标定实现咨询

单个圆形靶标相机标定方案说明

内置函数可用性说明

可以直接使用OpenCV内置的cv2.calibrateCamera()标定函数完成该场景下的标定,该函数仅要求输入匹配的3D世界坐标系点位和对应的2D图像像素点位,不对靶标类型做限制。

具体实现步骤

  • 采集至少15~20帧不同角度、不同距离、不同姿态的圆形靶标图像,要求所有图像中圆形完整可见,拍摄姿态尽量覆盖全视野,避免出现相近姿态的重复采样
  • 对每帧图像做灰度化、高斯模糊、二值化预处理,使用cv2.findContours()轮廓检测或cv2.HoughCircles()霍夫圆检测提取圆形区域,拟合得到图像中圆形的圆心像素坐标和成像半径
  • 构造3D-2D匹配点对:将靶标平面设为世界坐标系的Z=0平面,圆心设为世界坐标系原点,根据已知的真实半径生成圆心以及圆周均匀采样点的3D坐标;对应2D坐标为检测到的图像圆心和拟合圆周上相同角度的像素坐标
  • 将所有帧的3D点集合、2D点集合、相机图像分辨率输入cv2.calibrateCamera(),即可解算得到相机内参矩阵、畸变系数以及每帧靶标对应的外参矩阵

注意事项

  • 需保证靶标平面的平整度,避免平面变形带来的系统误差
  • 若要提升标定精度,可对检测到的圆形轮廓做亚像素拟合,替代霍夫圆检测直接输出的整数坐标,降低2D点检测误差
  • 采集图像时要尽量保证姿态差异足够大,避免出现退化位姿导致标定结果精度不足

核心实现代码片段

import cv2
import numpy as np

# 预设标定参数
REAL_CIRCLE_RADIUS = 0.05  # 圆形靶标的真实半径,单位为米
CIRCUMFERENCE_SAMPLE_COUNT = 16  # 圆周采样点数量
CAMERA_RESOLUTION = (1280, 720)  # 相机输出图像的分辨率

# 构造固定的3D世界坐标点(靶标平面为Z=0平面)
objp = np.zeros((CIRCUMFERENCE_SAMPLE_COUNT + 1, 3), np.float32)
objp[0] = [0, 0, 0]  # 圆心对应3D坐标
for i in range(CIRCUMFERENCE_SAMPLE_COUNT):
    theta = 2 * np.pi * i / CIRCUMFERENCE_SAMPLE_COUNT
    objp[i+1] = [REAL_CIRCLE_RADIUS * np.cos(theta), REAL_CIRCLE_RADIUS * np.sin(theta), 0]

# 存储所有帧的匹配点对
obj_points = []  # 存储3D世界坐标
img_points = []  # 存储对应2D图像坐标

# 替换为你自己的标定图像路径列表
calib_image_paths = ["img1.jpg", "img2.jpg", "img3.jpg"]

for img_path in calib_image_paths:
    img = cv2.imread(img_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 霍夫圆检测提取圆形靶标
    circles = cv2.HoughCircles(
        gray, cv2.HOUGH_GRADIENT, dp=1.2, minDist=200,
        param1=50, param2=30, minRadius=10, maxRadius=300
    )
    if circles is not None:
        circles = np.uint16(np.around(circles))[0][0]
        cx, cy, r = circles[0], circles[1], circles[2]
        # 构造对应2D坐标点
        imgp = np.zeros((CIRCUMFERENCE_SAMPLE_COUNT + 1, 2), np.float32)
        imgp[0] = [cx, cy]
        for i in range(CIRCUMFERENCE_SAMPLE_COUNT):
            theta = 2 * np.pi * i / CIRCUMFERENCE_SAMPLE_COUNT
            imgp[i+1] = [cx + r * np.cos(theta), cy + r * np.sin(theta)]
        obj_points.append(objp)
        img_points.append(imgp)

# 执行相机标定
ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.calibrateCamera(
    obj_points, img_points, CAMERA_RESOLUTION, None, None
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 17:57:03