opencv摄像头标定程序实现

摄像头标定是计算机视觉中的一个重要步骤,用于确定摄像头的内参(如焦距、主点、畸变系数等)和外参(如旋转矩阵和平移向量)。OpenCV 提供了方便的工具来进行摄像头标定。下面分别给出 C++ 和 Python 的实现。

1. C++ 实现

1.1 准备工作
  • 准备一个棋盘格(如 9x6 的棋盘格)。
  • 拍摄多张棋盘格图片(至少 10-15 张),确保棋盘格在不同位置和角度。
1.2 代码实现
cpp 复制代码
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>

using namespace cv;
using namespace std;

int main() {
    // 棋盘格的尺寸
    Size boardSize(9, 6);
    float squareSize = 1.0f; // 棋盘格方块的物理尺寸(单位:米)

    // 存储棋盘格角点的三维坐标
    vector<vector<Point3f>> objectPoints;
    // 存储棋盘格角点的二维图像坐标
    vector<vector<Point2f>> imagePoints;

    // 生成棋盘格的三维坐标
    vector<Point3f> obj;
    for (int i = 0; i < boardSize.height; i++) {
        for (int j = 0; j < boardSize.width; j++) {
            obj.push_back(Point3f(j * squareSize, i * squareSize, 0));
        }
    }

    // 读取图像
    vector<String> imagePaths;
    glob("path/to/calibration_images/*.jpg", imagePaths);

    for (size_t i = 0; i < imagePaths.size(); i++) {
        Mat image = imread(imagePaths[i]);
        Mat gray;
        cvtColor(image, gray, COLOR_BGR2GRAY);

        // 查找棋盘格角点
        vector<Point2f> corners;
        bool found = findChessboardCorners(gray, boardSize, corners);

        if (found) {
            // 亚像素精确化
            cornerSubPix(gray, corners, Size(11, 11), Size(-1, -1),
                         TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 30, 0.001));

            imagePoints.push_back(corners);
            objectPoints.push_back(obj);

            // 绘制并显示角点
            drawChessboardCorners(image, boardSize, Mat(corners), found);
            imshow("Corners", image);
            waitKey(500);
        }
    }

    // 标定摄像头
    Mat cameraMatrix, distCoeffs;
    vector<Mat> rvecs, tvecs;
    double rms = calibrateCamera(objectPoints, imagePoints, gray.size(), cameraMatrix, distCoeffs, rvecs, tvecs);

    cout << "RMS error: " << rms << endl;
    cout << "Camera matrix: " << cameraMatrix << endl;
    cout << "Distortion coefficients: " << distCoeffs << endl;

    // 保存标定结果
    FileStorage fs("camera_calibration.yml", FileStorage::WRITE);
    fs << "camera_matrix" << cameraMatrix;
    fs << "distortion_coefficients" << distCoeffs;
    fs.release();

    return 0;
}
1.3 运行说明
  • 将棋盘格图片放在 path/to/calibration_images/ 目录下。
  • 运行程序后,标定结果将保存在 camera_calibration.yml 文件中。

2. Python 实现

2.1 准备工作
  • 准备一个棋盘格(如 9x6 的棋盘格)。
  • 拍摄多张棋盘格图片(至少 10-15 张),确保棋盘格在不同位置和角度。
2.2 代码实现
python 复制代码
import cv2
import numpy as np
import glob

# 棋盘格的尺寸
board_size = (9, 6)
square_size = 1.0  # 棋盘格方块的物理尺寸(单位:米)

# 存储棋盘格角点的三维坐标
object_points = []
# 存储棋盘格角点的二维图像坐标
image_points = []

# 生成棋盘格的三维坐标
objp = np.zeros((board_size[0] * board_size[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:board_size[0], 0:board_size[1]].T.reshape(-1, 2)
objp *= square_size

# 读取图像
images = glob.glob('path/to/calibration_images/*.jpg')

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

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

    if ret:
        # 亚像素精确化
        corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1),
                                    (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001))

        image_points.append(corners2)
        object_points.append(objp)

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

# 标定摄像头
ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.calibrateCamera(object_points, image_points, gray.shape[::-1], None, None)

print("RMS error:", ret)
print("Camera matrix:\n", camera_matrix)
print("Distortion coefficients:\n", dist_coeffs)

# 保存标定结果
np.savez('camera_calibration.npz', camera_matrix=camera_matrix, dist_coeffs=dist_coeffs)

cv2.destroyAllWindows()
2.3 运行说明
  • 将棋盘格图片放在 path/to/calibration_images/ 目录下。
  • 运行程序后,标定结果将保存在 camera_calibration.npz 文件中。

3. 总结

  • C++ 和 Python 的实现步骤基本相同,主要包括:准备棋盘格、查找角点、亚像素精确化、标定摄像头、保存标定结果。
  • 标定结果可以用于后续的图像校正、三维重建等任务。
相关推荐
xm一点不soso10 小时前
ROS2+OpenCV综合应用--11. AprilTag标签码跟随
人工智能·opencv·计算机视觉
昨夜雨疏风骤z15 小时前
如何在Windows上编译OpenCV4.7.0
windows·opencv
jndingxin16 小时前
OpenCV相机标定与3D重建(47)从两幅图像中的一组匹配点恢复相机的姿态(旋转和平移)函数recoverPose()的使用
opencv·3d
Quz17 小时前
OpenCV在现代社会中的应用
人工智能·opencv·计算机视觉
17´19 小时前
从0到机器视觉工程师(六):配置OpenCV和Qt环境
qt·opencv
湫ccc21 小时前
《Opencv》信用卡信息识别项目
人工智能·python·opencv·计算机视觉
old_power21 小时前
OpenCV 4.5至4.10版本更新概述
opencv·计算机视觉
AI+程序员在路上1 天前
OpenCV轮廓相关操作API (C++)
c++·人工智能·opencv
是十一月末1 天前
Opencv图片的旋转和图片的模板匹配
人工智能·python·opencv·计算机视觉