多相机系统中的相机标定(Calibration)

相机标定(Camera Calibration)在多相机系统和三维视觉等领域极为重要,不仅能构建二维相机平面和三维世界坐标的相互关系,更重要的是能构建真实世界的尺度信息

在三维重建领域,COLMAP或者DUST3R被用作常见的相机标定算法,通过立体匹配的方式得到相机的位姿,可以用于重建任务。但在相机标定领域,COLMAP真的够用了吗?答:远远不够用。先不说其在稀疏视点下通常无法完成标定,更重要的是,其估计的只是相对位姿,无法给出真实世界的尺度。

本文介绍一种用棋盘格标定板的相机标定步骤。
1,棋盘格的挑选与购买,要求:够大、不要有明显的镜面反射。本文采用的是GP400规格的标定板。
在这里插入图片描述
2,相机图像采集,实验中我用了三个相机。
3,标定程序:

import os
import os.path as osp
import cv2
import numpy as np

# 定义棋盘格的尺寸
chessboard_size = (11, 8)  # 内部角点的数量
square_size = 0.03         # 每个方格的实际大小(可以用物理测量值替换,单位为米)

# 准备标定所需的真实世界坐标点
objp = np.zeros((chessboard_size[0] * chessboard_size[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:chessboard_size[0], 0:chessboard_size[1]].T.reshape(-1, 2)
objp *= square_size

# 用于存储所有图像的角点与对应的世界坐标
obj_points = []  # 世界坐标系中的 3D 点
img_points = []  # 图像平面中的 2D 点

root = "img/"
images = [osp.join(root, pp) for pp in sorted(os.listdir(root))]
print(images)

for i, image_path in enumerate(images):
    img = cv2.imread(image_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 找到棋盘格角点
    ret, corners = cv2.findChessboardCorners(gray, chessboard_size, None)
    print(ret)

    if ret:
        obj_points.append(objp)
        img_points.append(corners)

        # 在图像上绘制并显示角点(可选)
        cv2.drawChessboardCorners(img, chessboard_size, corners, ret)
        cv2.imwrite(f"viz_{i}.jpg", img)


# 标定相机
ret, camera_matrix, distortion_coeffs, rvecs, tvecs = cv2.calibrateCamera(
    obj_points, img_points, gray.shape[::-1], None, None)


for i, (r, t) in enumerate(zip(rvecs, tvecs)):
    R, _ = cv2.Rodrigues(r)
    Rt = np.hstack((R, t))
    print(Rt)
    np.save(f"parm/{i}_extrinsic.npy", Rt)


# 输出结果
print("相机内参矩阵:")
print(camera_matrix)
np.save("intrinsic.npy", camera_matrix)

print("\n畸变系数:")
print(distortion_coeffs)

# 可选:保存标定结果
np.savez("camera_calibration.npz", camera_matrix=camera_matrix, distortion_coeffs=distortion_coeffs)

# 校正图像
for i, image_path in enumerate(images):
    img = cv2.imread(image_path)
    h, w = img.shape[:2]
    new_camera_matrix, roi = cv2.getOptimalNewCameraMatrix(camera_matrix, distortion_coeffs, (w, h), 1, (w, h))
    dst = cv2.undistort(img, camera_matrix, distortion_coeffs, None, new_camera_matrix)
    cv2.imwrite(f"undist_{i}.jpg", dst)

其中比较关键的是设置棋盘格的角点数量和方块变长(用于绝对尺度的估计)

实验结果:
请添加图片描述
三张视图的角点全部检测到。咱们通过一个可视化程序可以看到:
请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木盏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

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

抵扣说明:

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

余额充值