当前位置: 首页 > article >正文

opencv摄像头标定程序实现

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

1. C++ 实现

1.1 准备工作
  • 准备一个棋盘格(如 9x6 的棋盘格)。
  • 拍摄多张棋盘格图片(至少 10-15 张),确保棋盘格在不同位置和角度。
1.2 代码实现
#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 代码实现
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 的实现步骤基本相同,主要包括:准备棋盘格、查找角点、亚像素精确化、标定摄像头、保存标定结果。
  • 标定结果可以用于后续的图像校正、三维重建等任务。

http://www.kler.cn/a/471873.html

相关文章:

  • Eclipse配置Tomcat服务器(最全图文详解)
  • 《Spring Framework实战》4:Spring Framework 文档
  • Python学习笔记:显示进度条
  • Mysql--基础篇--数据类型(整数,浮点数,日期,枚举,二进制,空间类型等)
  • ARM发布Armv9.5架构:迈向更强性能与灵活性的新时代
  • vue 什么时候使用v-if 什么时候使用v-show
  • Go语言的语法
  • 会员制营销与门店业绩提升:以开源AI智能名片S2B2C商城小程序为例的深度剖析
  • 基于微信小程序的考研资料分享系统的设计与实现springboot+论文源码调试讲解
  • 【阅读】认知觉醒
  • Mermaid 使用教程之流程图 - 从入门到精通
  • 2025新春烟花代码(一)HTML5夜景放烟花绽放动画效果
  • 基于Thinkphp6+uniapp的陪玩陪聊软件开发方案分析
  • flutter web 路由问题
  • 【Qt】C++11 Lambda表达式
  • C语言文件学习
  • 数据库回滚:大祸临头时
  • 复合机器人助力手机壳cnc加工向自动化升级
  • JAVA学习记录1
  • 【Linux】Linux的权限问题
  • 李正国教授、张钊博士到访美尔斯通,共绘心磁图技术新蓝图
  • jenkins入门10--自动化构建
  • 嵌入式驱动开发详解11(INPUT子系统)
  • 基于Spring Boot的社区老人健康信息管理系统的设计与实现(LW+源码+讲解)
  • 加速科技荣获“浙江省企业研究院”认定
  • with as提高sql的执行效率