OpenCV Calib3d 模块使用指南

一、模块概述

OpenCV 的 Calib3d 模块主要提供相机校准和 3D 重建相关的功能。通过该模块,我们可以对相机进行标定以去除镜头畸变,还能从 2D 图像中恢复 3D 信息。下面将详细介绍该模块的主要类和函数,以及它们在不同应用场景中的实现。

二、主要函数详解

(一)相机校准相关函数

1. cv.findChessboardCorners()
  • 功能:在图像中查找棋盘格角点。
  • 参数
    • image:输入的灰度图像。
    • patternSize:棋盘格内角点的行数和列数(如 (7, 7) 表示 7 行 7 列)。
    • flags:用于指定查找角点的方法,如 cv.CALIB_CB_ADAPTIVE_THRESH 等。
  • 返回值
    • ret:是否成功找到角点的布尔值。
    • corners:找到的角点坐标。
示例代码

python

复制代码
import cv2 as cv
import numpy as np

# 读取图像
img = cv.imread('chessboard.jpg')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# 棋盘格内角点的行数和列数
pattern_size = (7, 7)

# 查找角点
ret, corners = cv.findChessboardCorners(gray, pattern_size)

if ret:
    # 绘制角点
    cv.drawChessboardCorners(img, pattern_size, corners, ret)
    cv.imshow('Corners', img)
    cv.waitKey(0)
2. cv.calibrateCamera()
  • 功能:对相机进行校准,计算相机的内参矩阵、畸变系数等。
  • 参数
    • objectPoints:世界坐标系中棋盘格角点的三维坐标。
    • imagePoints:图像中对应的角点坐标。
    • imageSize:图像的尺寸。
    • cameraMatrix:输出的相机内参矩阵。
    • distCoeffs:输出的畸变系数。
    • rvecs:输出的旋转向量。
    • tvecs:输出的平移向量。
  • 返回值
    • ret:校准的重投影误差。
示例代码

python

复制代码
import cv2 as cv
import numpy as np

# 棋盘格内角点的行数和列数
pattern_size = (7, 7)
# 世界坐标系中棋盘格角点的三维坐标
objp = np.zeros((pattern_size[0] * pattern_size[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2)

# 存储世界坐标系和图像坐标系中的点
objpoints = []
imgpoints = []

# 读取一系列图像
for i in range(1, 11):
    img = cv.imread(f'chessboard_{i}.jpg')
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    ret, corners = cv.findChessboardCorners(gray, pattern_size)
    if ret:
        objpoints.append(objp)
        imgpoints.append(corners)

# 图像尺寸
image_size = (img.shape[1], img.shape[0])

# 相机校准
ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv.calibrateCamera(objpoints, imgpoints, image_size, None, None)

print(f"重投影误差: {ret}")
print(f"相机内参矩阵: \n{camera_matrix}")
print(f"畸变系数: \n{dist_coeffs}")

(二)3D 重建相关函数

1. cv.solvePnP()
  • 功能:根据 3D 点和对应的 2D 点求解相机的位姿(旋转和平移)。
  • 参数
    • objectPoints:世界坐标系中 3D 点的坐标。
    • imagePoints:图像中对应的 2D 点坐标。
    • cameraMatrix:相机的内参矩阵。
    • distCoeffs:相机的畸变系数。
    • rvec:输出的旋转向量。
    • tvec:输出的平移向量。
  • 返回值
    • ret:是否成功求解的布尔值。
示例代码

python

复制代码
import cv2 as cv
import numpy as np

# 相机内参矩阵和畸变系数(假设已经通过校准得到)
camera_matrix = np.array([[1000, 0, 320], [0, 1000, 240], [0, 0, 1]], dtype=np.float32)
dist_coeffs = np.zeros((5, 1), dtype=np.float32)

# 世界坐标系中 3D 点的坐标
object_points = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype=np.float32)
# 图像中对应的 2D 点坐标
image_points = np.array([[100, 100], [200, 100], [100, 200], [100, 100]], dtype=np.float32)

# 求解相机位姿
ret, rvec, tvec = cv.solvePnP(object_points, image_points, camera_matrix, dist_coeffs)

if ret:
    print(f"旋转向量: \n{rvec}")
    print(f"平移向量: \n{tvec}")
2. cv.reprojectImageTo3D()
  • 功能:将视差图转换为 3D 点云。
  • 参数
    • disparity:输入的视差图。
    • Q:用于从视差图恢复 3D 信息的重投影矩阵。
  • 返回值
    • points_3d:输出的 3D 点云。
示例代码

python

复制代码
import cv2 as cv
import numpy as np

# 假设已经有视差图和重投影矩阵
disparity = cv.imread('disparity_map.png', cv.IMREAD_GRAYSCALE)
Q = np.array([[1, 0, 0, -320], [0, 1, 0, -240], [0, 0, 0, 1000], [0, 0, 1 / 100, 0]], dtype=np.float32)

# 从视差图恢复 3D 点云
points_3d = cv.reprojectImageTo3D(disparity, Q)

print(f"3D 点云形状: {points_3d.shape}")

三、应用场景实现

(一)相机标定(用于去除镜头畸变)

相机标定的主要目的是计算相机的内参矩阵和畸变系数,以便对图像进行去畸变处理。以下是一个完整的相机标定和去畸变的示例代码:

python

复制代码
import cv2 as cv
import numpy as np

# 棋盘格内角点的行数和列数
pattern_size = (7, 7)
# 世界坐标系中棋盘格角点的三维坐标
objp = np.zeros((pattern_size[0] * pattern_size[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2)

# 存储世界坐标系和图像坐标系中的点
objpoints = []
imgpoints = []

# 读取一系列图像
for i in range(1, 11):
    img = cv.imread(f'chessboard_{i}.jpg')
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    ret, corners = cv.findChessboardCorners(gray, pattern_size)
    if ret:
        objpoints.append(objp)
        imgpoints.append(corners)

# 图像尺寸
image_size = (img.shape[1], img.shape[0])

# 相机校准
ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv.calibrateCamera(objpoints, imgpoints, image_size, None, None)

# 读取待去畸变的图像
img = cv.imread('test_image.jpg')

# 去畸变
undistorted_img = cv.undistort(img, camera_matrix, dist_coeffs)

cv.imshow('Original Image', img)
cv.imshow('Undistorted Image', undistorted_img)
cv.waitKey(0)

(二)3D 重建(如从 2D 图像恢复 3D 信息)

以下是一个简单的从 2D 图像对进行 3D 重建的示例代码,包括相机校准、求解相机位姿和恢复 3D 点云:

python

复制代码
import cv2 as cv
import numpy as np

# 棋盘格内角点的行数和列数
pattern_size = (7, 7)
# 世界坐标系中棋盘格角点的三维坐标
objp = np.zeros((pattern_size[0] * pattern_size[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2)

# 存储世界坐标系和图像坐标系中的点
objpoints = []
imgpoints = []

# 读取一系列图像
for i in range(1, 11):
    img = cv.imread(f'chessboard_{i}.jpg')
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    ret, corners = cv.findChessboardCorners(gray, pattern_size)
    if ret:
        objpoints.append(objp)
        imgpoints.append(corners)

# 图像尺寸
image_size = (img.shape[1], img.shape[0])

# 相机校准
ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv.calibrateCamera(objpoints, imgpoints, image_size, None, None)

# 读取左右图像
img_left = cv.imread('left_image.jpg')
img_right = cv.imread('right_image.jpg')

# 转换为灰度图像
gray_left = cv.cvtColor(img_left, cv.COLOR_BGR2GRAY)
gray_right = cv.cvtColor(img_right, cv.COLOR_BGR2GRAY)

# 创建立体匹配器
stereo = cv.StereoBM_create(numDisparities=16, blockSize=15)
# 计算视差图
disparity = stereo.compute(gray_left, gray_right)

# 计算重投影矩阵
R = np.eye(3)
T = np.array([[100, 0, 0]]).T
Q = cv.stereoRectify(camera_matrix, dist_coeffs, camera_matrix, dist_coeffs, image_size, R, T)[4]

# 从视差图恢复 3D 点云
points_3d = cv.reprojectImageTo3D(disparity, Q)

print(f"3D 点云形状: {points_3d.shape}")

四、注意事项

  • 棋盘格图像:在进行相机标定时,需要使用一系列不同角度和位置的棋盘格图像,以确保校准结果的准确性。
  • 图像质量:图像的质量会影响角点检测和 3D 重建的结果,因此应尽量使用清晰、光照均匀的图像。
  • 参数选择 :在使用 cv.StereoBM_create() 等函数时,需要根据实际情况选择合适的参数,如 numDisparitiesblockSize 等。

通过以上内容,你可以了解到 Calib3d 模块的主要功能和使用方法,以及如何在不同的应用场景中实现相机标定和 3D 重建。

相关推荐
CoovallyAIHub3 小时前
为高空安全上双保险!无人机AI护航,YOLOv5秒判安全带,守护施工生命线
深度学习·算法·计算机视觉
才思喷涌的小书虫3 小时前
小白玩转 DINO-X MCP(2):基于 DINO-X MCP 搭建饮食规划工作流
计算机视觉·mcp
彩旗工作室4 小时前
腾讯混元3D系列开源模型:从工业级到移动端的本地部署
3d·开源·腾讯混元
CG_MAGIC4 小时前
主流 3D 模型格式(FBX/OBJ/DAE/GLTF)材质支持与转换操作指南
3d·渲染·动画·材质·贴图·3d 模型格式·材质支持与转换操作指南
计算机sci论文精选4 小时前
CVPR 2025 | 具身智能 | HOLODECK:一句话召唤3D世界,智能体的“元宇宙练功房”来了
人工智能·深度学习·机器学习·计算机视觉·机器人·cvpr·具身智能
山烛5 小时前
OpenCV 图像处理基础操作指南(二)
人工智能·python·opencv·计算机视觉
CoovallyAIHub6 小时前
线性复杂度破局!Swin Transformer 移位窗口颠覆高分辨率视觉建模
深度学习·算法·计算机视觉
R-G-B9 小时前
【P38 6】OpenCV Python——图片的运算(算术运算、逻辑运算)加法add、subtract减法、乘法multiply、除法divide
人工智能·python·opencv·图片的运算·图片加法add·图片subtract减法·图片乘法multiply
硅谷秋水10 小时前
在相机空间中落地动作:以观察为中心的视觉-语言-行动策略
机器学习·计算机视觉·语言模型·机器人
hllqkbb10 小时前
从 SGD 到梯度累积:Epoch、Batch、Step 的关系全解析
开发语言·人工智能·opencv·计算机视觉·batch