搞定相机内参:用Open3D+OpenCV实现张正友标定法(附Python代码)

搞定相机内参:用Open3D+OpenCV实现张正友标定法(附Python代码)

【免费下载链接】Open3D 【免费下载链接】Open3D 项目地址: https://gitcode.com/gh_mirrors/open/Open3D

你是否还在为相机标定 accuracy 不足而头疼?是否尝试过多种方法却始终无法获得稳定的内参矩阵?本文将带你用Open3D结合OpenCV实现工业级相机标定方案,从棋盘格图像采集到内参矩阵计算,全程代码可复现,让你1小时内掌握张正友标定法核心原理。

读完本文你将获得:

  • 张正友标定法数学原理可视化解析
  • Open3D与OpenCV联合编程最佳实践
  • 相机畸变系数校正完整工作流
  • 标定结果评估与误差分析方法

标定原理与Open3D相机模型

相机内参(Camera Intrinsics)是描述相机光学特性的关键参数,包括焦距(fx, fy)、主点(cx, cy)和畸变系数(k1, k2, p1, p2, k3)。张正友标定法通过拍摄多视角棋盘格图像,建立世界坐标系到图像坐标系的映射关系,求解内参矩阵。

Open3D提供了完整的相机模型支持,通过PinholeCameraIntrinsic类实现内参管理。其核心数据结构如下:

# 示例:创建相机内参对象
intrinsic = o3d.camera.PinholeCameraIntrinsic(
    width=640, height=480,
    fx=525.0, fy=525.0,
    cx=319.5, cy=239.5
)

内参矩阵表示为:

[fx,  0, cx]
[ 0, fy, cy]
[ 0,  0,  1]

标定流程与OpenCV集成方案

1. 标定环境搭建

Open3D通过Python接口与OpenCV无缝集成,推荐使用以下环境配置:

pip install open3d opencv-python numpy matplotlib

2. 棋盘格图像采集规范

为获得理想标定结果,需遵循:

  • 棋盘格尺寸建议:8×6内角点(如A4纸打印)
  • 拍摄角度:覆盖0°-60°倾斜范围
  • 图像数量:15-20张不同姿态

3. 联合编程实现步骤

以下是基于Open3D+OpenCV的标定实现代码:

import cv2
import numpy as np
import open3d as o3d

# 1. 准备棋盘格参数
chessboard_size = (8, 6)  # 内角点数量
square_size = 0.025       # 棋盘格方块边长(m)

# 2. 检测棋盘格角点
obj_points = []  # 世界坐标系点
img_points = []  # 图像坐标系点
objp = np.zeros((np.prod(chessboard_size), 3), np.float32)
objp[:, :2] = np.mgrid[0:chessboard_size[0], 0:chessboard_size[1]].T.reshape(-1, 2) * square_size

# 3. 读取标定图像并检测角点
images = ["calib_img1.jpg", "calib_img2.jpg", ...]  # 替换为实际图像路径
for img_path in images:
    img = cv2.imread(img_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # 检测棋盘格角点
    ret, corners = cv2.findChessboardCorners(gray, chessboard_size, None)
    
    if ret:
        obj_points.append(objp)
        # 亚像素精确化
        corners2 = cv2.cornerSubPix(
            gray, corners, (11, 11), (-1, -1),
            criteria=(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
        )
        img_points.append(corners2)

# 4. 调用OpenCV标定函数
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(
    obj_points, img_points, gray.shape[::-1], None, None
)

# 5. 转换为Open3D内参对象
o3d_intrinsic = o3d.camera.PinholeCameraIntrinsic(
    width=gray.shape[1],
    height=gray.shape[0],
    fx=mtx[0, 0],
    fy=mtx[1, 1],
    cx=mtx[0, 2],
    cy=mtx[1, 2]
)

# 6. 保存标定结果
o3d.io.write_pinhole_camera_intrinsic("camera_intrinsic.json", o3d_intrinsic)

标定结果可视化与评估

重投影误差计算

重投影误差是评估标定精度的关键指标,计算公式:

mean_error = 0
for i in range(len(obj_points)):
    img_points2, _ = cv2.projectPoints(obj_points[i], rvecs[i], tvecs[i], mtx, dist)
    error = cv2.norm(img_points[i], img_points2, cv2.NORM_L2) / len(img_points2)
    mean_error += error
print(f"平均重投影误差: {mean_error/len(obj_points):.4f}像素")

Open3D可视化验证

使用Open3D可视化标定结果:

# 加载点云并应用内参
pcd = o3d.io.read_point_cloud("test.pcd")
vis = o3d.visualization.Visualizer()
vis.create_window()
vis.add_geometry(pcd)

# 设置相机内参
render_option = vis.get_render_option()
render_option.background_color = [0.8, 0.8, 0.8]
vis.get_view_control().convert_from_pinhole_camera_intrinsic(o3d_intrinsic)

vis.run()
vis.destroy_window()

实战案例:RGBD相机标定

以Intel RealSense D435i为例,结合examples/python/pipelines/rgbd_odometry.py实现深度相机标定:

  1. 采集RGBD数据:使用RealSenseRecorder录制包含棋盘格的RGBD序列
  2. 提取彩色图像:从RGBD数据流中提取RGB帧用于标定
  3. 执行标定流程:应用前述标定代码计算内参
  4. 优化深度图:使用标定得到的内参校正深度图畸变
# 校正深度图示例
depth_raw = o3d.io.read_image("depth.png")
color_raw = o3d.io.read_image("color.jpg")
rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
    color_raw, depth_raw
)

# 应用内参校正
pcd = o3d.geometry.PointCloud.create_from_rgbd_image(
    rgbd_image, o3d_intrinsic
)

常见问题与解决方案

标定误差过大怎么办?

  • 确保棋盘格打印精度,避免透视变形
  • 增加不同角度图像数量(建议≥20张)
  • 检查图像是否存在运动模糊
  • 优化角点检测参数,使用亚像素精确化

Open3D与OpenCV坐标系转换

Open3D采用计算机视觉标准坐标系,与OpenCV一致,但需注意:

  • 图像原点:左上角(0,0)
  • 相机坐标系:x右,y下,z前

内参文件管理

推荐使用JSON格式保存内参,便于Open3D加载:

# 保存内参
o3d.io.write_pinhole_camera_intrinsic("intrinsics.json", o3d_intrinsic)

# 加载内参
loaded_intrinsic = o3d.io.read_pinhole_camera_intrinsic("intrinsics.json")

总结与扩展

本文详细介绍了基于Open3D和OpenCV的相机标定方案,通过张正友标定法实现高精度内参估计。核心要点包括:

  1. 标定原理:利用棋盘格平面与图像平面的单应性矩阵求解内参
  2. 工具链:OpenCV负责角点检测与标定计算,Open3D处理3D可视化与应用
  3. 精度优化:亚像素角点检测+多视角平均提升标定稳定性

扩展方向:

  • 双目相机标定:结合Open3D双目视觉模块
  • 动态标定:使用AzureKinectMKVReader处理视频流标定
  • 深度学习优化:集成Open3D-ML实现端到端标定

建议收藏本文代码模板,关注项目官方文档获取最新API更新。如有疑问,欢迎在评论区留言讨论标定结果优化技巧。

下期预告:《基于Open3D的点云配准:从ICP到全局优化》

【免费下载链接】Open3D 【免费下载链接】Open3D 项目地址: https://gitcode.com/gh_mirrors/open/Open3D

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值