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 的实现步骤基本相同,主要包括:准备棋盘格、查找角点、亚像素精确化、标定摄像头、保存标定结果。
  • 标定结果可以用于后续的图像校正、三维重建等任务。
相关推荐
爱打代码的小林1 天前
OpenCV 实战:基于 SIFT 特征匹配的图像认证系统
人工智能·opencv·计算机视觉
Daydream.V1 天前
OpenCV高端操作——特征检测(附案例实战)
人工智能·opencv·计算机视觉
爱打代码的小林1 天前
OpenCV 实战:为视频添加椒盐噪声并实现中值滤波去噪
人工智能·opencv·计算机视觉
纤纡.1 天前
基于 OpenCV 的计算机视觉实战:从图像矫正到指纹识别
人工智能·opencv·计算机视觉
Westward-sun.1 天前
OpenCV图像特征提取:Harris角点检测与SIFT特征提取实战
人工智能·opencv·计算机视觉
梦醒过后说珍重2 天前
医学图像超分辨率:如何构建“教科书级”的模型评测与交互式可视化流水线?
opencv
格林威2 天前
工业相机参数解析:曝光时间与运动模糊的“生死博弈”
c++·人工智能·数码相机·opencv·算法·计算机视觉·工业相机
AI科技星2 天前
全尺度角速度统一:基于 v ≡ c 的纯推导与验证
c语言·开发语言·人工智能·opencv·算法·机器学习·数据挖掘
格林威3 天前
C++ 工业视觉实战:Bayer 图转 RGB 的 3 种核心算法(邻域平均、双线性、OpenCV 源码级优化)
开发语言·c++·人工智能·opencv·算法·计算机视觉·工业相机
格林威3 天前
工业相机图像高速存储(C++版):RAID 0 NVMe SSD 阵列方法,附堡盟相机实战代码!
开发语言·c++·人工智能·数码相机·opencv·计算机视觉·视觉检测