2024-12-05OpenCV高级-立体视觉

发布于:2024-12-06 ⋅ 阅读:(101) ⋅ 点赞:(0)

OpenCV高级-3D重建与立体视觉

OpenCV相机标定


使用 OpenCV 进行相机标定是一个常见的任务,可以用来校正镜头畸变、计算相机的内参和外参等。下面是一个完整的示例代码,展示了如何使用 cv2.findChessboardCorns() 查找棋盘角点,使用 cv2.calibrateCamera() 进行相机标定,并计算相机的内参与外参,最后评估标定结果。

1. 导入必要的库

import cv2
import numpy as np
import glob

2. 准备标定图像

假设你有一些标定图像,这些图像是棋盘格图像。你可以将这些图像放在一个文件夹中,然后使用 glob 模块来读取这些图像。

# 棋盘格参数
chessboard_size = (9, 6)  # 棋盘格内角点的数量
square_size = 1.0  # 棋盘格每个方格的边长,单位可以是毫米、厘米等

# 准备对象点,如 (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
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) * square_size

# 存储对象点和图像点的列表
objpoints = []  # 3d点在世界坐标系中的位置
imgpoints = []  # 2d点在图像平面中的位置

3. 读取图像并查找棋盘角点

# 读取所有标定图像
images = glob.glob('calibration_images/*.jpg')

for fname in images:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

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

    if ret:
        objpoints.append(objp)
        imgpoints.append(corners)

        # 绘制并显示角点
        cv2.drawChessboardCorners(img, chessboard_size, corners, ret)
        cv2.imshow('img', img)
        cv2.waitKey(500)

cv2.destroyAllWindows()

4. 进行相机标定

# 进行相机标定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)

5. 计算并评估标定结果

# 计算重投影误差
mean_error = 0
for i in range(len(objpoints)):
    imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
    error = cv2.norm(imgpoints[i], imgpoints2, cv2.NORM_L2) / len(imgpoints2)
    mean_error += error

print(f"Total re-projection error: {mean_error / len(objpoints)}")

# 保存标定结果
np.savez('calibration_output.npz', ret=ret, mtx=mtx, dist=dist, rvecs=rvecs, tvecs=tvecs)

6. 读取并使用标定结果

# 读取标定结果
calibration_data = np.load('calibration_output.npz')
ret = calibration_data['ret']
mtx = calibration_data['mtx']
dist = calibration_data['dist']
rvecs = calibration_data['rvecs']
tvecs = calibration_data['tvecs']

# 打印标定结果
print("Camera matrix:\n", mtx)
print("Distortion coefficients:\n", dist)
print("Rotation vectors:\n", rvecs)
print("Translation vectors:\n", tvecs)

7. 校正图像

# 读取一张图像并校正畸变
img = cv2.imread('calibration_images/1.jpg')
h, w = img.shape[:2]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1, (w, h))

# 校正图像
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)

# 剪裁图像
x, y, w, h = roi
dst = dst[y:y+h, x:x+w]
cv2.imwrite('calibrated_image.png', dst)

以上代码展示了如何使用 OpenCV 进行相机标定,包括查找棋盘角点、进行标定、计算重投影误差、保存和读取标定结果,以及校正图像畸变。希望这些内容对你有所帮助!


网站公告

今日签到

点亮在社区的每一天
去签到