OpenCV 棋盘格相机标定(保姆版)

news2024/11/15 2:22:50

目录

一、概述

1.1标定原理

1.2实现步骤

1.3应用场景

二、代码

2.1 cv2.calibrateCamera函数

2.1.1输入参数

2.1.2输出参数

2.2完整代码

三、实现效果

3.1处理图像

3.2内参与畸变系数


一、概述

        使用 OpenCV 进行相机标定,通常需要拍摄多张包含棋盘格标定板的图像,然后通过这些图像计算相机的内参和畸变系数。OpenCV中使用 cv2.calibrateCamera 使用非线性最小二乘法(如 Levenberg-Marquardt 算法)来最小化重投影误差,即实际图像点与由相机模型预测的图像点之间的误差。通过迭代优化,函数求解出相机的内参、畸变系数以及每张图像的外参。

1.1标定原理

        相机标定是确定相机成像模型中的内参和外参的过程。内参(内参数)描述了相机自身的特性,而外参(外参数)描述了相机的姿态,即相机坐标系相对于世界坐标系的位置和方向。

1.2实现步骤

1.准备标定板
        标定板通常是一个已知尺寸的棋盘格或圆点阵列。标定板上的每个角点或圆心位置已知,可以用作 3D 世界坐标系中的参考点。
2.拍摄多张标定板图像
        从不同角度拍摄多张包含标定板的图像,以覆盖尽可能多的视角变化。这些图像将用于提取特征点,进行相机标定。
3.检测标定板角点
        使用图像处理算法(如 OpenCV 的 cv2.findChessboardCorners)在每张图像中检测标定板的角点或圆心,并记录其像素坐标。
4.优化角点位置
        为了提高精度,使用亚像素级别的优化方法(如 cv2.cornerSubPix)进一步优化角点的位置。
5.准备 3D-2D 点对
        根据标定板的已知尺寸和角点数量,准备每张图像的 3D 世界坐标点(实际坐标)和对应的 2D 图像点(像素坐标)。
6.计算相机内参和畸变系数
        使用标定算法(如 cv2.calibrateCamera)计算相机的内参矩阵和畸变系数。这一步需要将多张图像中的 3D-2D 点对输入到算法中,进行全局优化。
7.验证标定结果
        通过对标定图像进行去畸变处理和重投影误差分析,验证标定结果的准确性。可以使用一些新的图像进行验证,检查标定结果是否符合预期。

1.3应用场景


1.计算机视觉和机器人

  • 物体检测与识别:相机标定使得算法能够理解实际世界中的距离和比例,从而更准确地识别和定位物体。
  • 机器人导航:机器人通过相机感知环境,需要知道相机的精确位置和方向,以便于路径规划和避障。
  • 3D 重建:多视角相机标定是 3D 重建的基础,可以从多个视角拍摄的图像中恢复物体的 3D 形状。

2.增强现实(AR)

  • 虚拟物体叠加:为了将虚拟物体准确地叠加到现实场景中,必须知道相机的内参和外参,从而正确地渲染虚拟物体。
  • 实时跟踪:相机标定帮助实现实时跟踪和投影,使得虚拟内容能够随着相机移动而准确对齐。

3.工业检测

  • 尺寸测量:在工业检测中,准确测量物体的尺寸和位置需要相机的精确标定。
  • 缺陷检测:通过标定相机,可以从不同角度拍摄产品图像,检查产品表面是否存在缺陷。

二、代码

2.1 cv2.calibrateCamera函数

        cv2.calibrateCamera 使用非线性最小二乘法(如 Levenberg-Marquardt 算法)来最小化重投影误差,即实际图像点与由相机模型预测的图像点之间的误差。通过迭代优化,函数求解出相机的内参、畸变系数以及每张图像的外参。

retval, cameraMatrix, distCoeffs, rvecs, tvecs = cv2.calibrateCamera(objectPoints, imagePoints, imageSize[, cameraMatrix[, distCoeffs[, rvecs[, tvecs[, flags[, criteria]]]]]])

2.1.1输入参数

1.objectPoints:

  • 类型:list 或 np.ndarray
  • 形状:(N, 1, 3) 或 (N, 3),其中 N 是 3D 点的数量。
  • 描述:世界坐标系中的 3D 点集,每张图像一组。通常是标定板上的特征点在实际空间中的位置。

示例:对于 10 张图像,每张图像有 54 个角点,objectPoints 的形状为 [10, 54, 3]。
2.imagePoints:

  • 类型:list 或 np.ndarray
  • 形状:(N, 1, 2) 或 (N, 2),其中 N 是 2D 点的数量。
  • 描述:图像坐标系中的 2D 点集,每张图像一组。通常是从图像中检测到的标定板的特征点的像素坐标。

示例:对于 10 张图像,每张图像有 54 个角点,imagePoints 的形状为 [10, 54, 2]。
3.imageSize:

  • 类型:tuple
  • 形状:(width, height)
  • 描述:图像的大小,以像素为单位。

4.cameraMatrix(可选):

  • 类型:np.ndarray
  • 形状:(3, 3)
  • 描述:初始相机内参矩阵。如果提供,函数将使用它作为初始估计,否则使用默认值。

5.distCoeffs(可选):

  • 类型:np.ndarray
  • 形状:(5, 1) 或 (8, 1)
  • 描述:初始畸变系数。如果提供,函数将使用它作为初始估计,否则使用默认值。

6.rvecs(可选):

  • 类型:list
  • 形状:(N, 1, 3) 或 (N, 3)
  • 描述:每张图像的初始旋转向量。如果提供,函数将使用它作为初始估计。

7.tvecs(可选):

  • 类型:list
  • 形状:(N, 1, 3) 或 (N, 3)
  • 描述:每张图像的初始平移向量。如果提供,函数将使用它作为初始估计。

8.flags(可选):

  • 类型:整数
  • 描述:标定方法的标志。常用的标志包括:
  • cv2.CALIB_USE_INTRINSIC_GUESS:使用提供的内参矩阵作为初始估计。
  • cv2.CALIB_FIX_PRINCIPAL_POINT:固定主点(光学中心)。
  • cv2.CALIB_FIX_ASPECT_RATIO:固定焦距的纵横比。
  • cv2.CALIB_ZERO_TANGENT_DIST:假设切向畸变为零。

9.criteria(可选):

  • 类型:tuple
  • 描述:终止条件,表示迭代的最大次数和所需的最小精度。通常为 (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 1e-6)。

2.1.2输出参数

1.etval:

  • 类型:浮点数
  • 描述:标定的总重投影误差,表示优化过程的结果。

2.cameraMatrix:

  • 类型:np.ndarray
  • 形状:(3, 3)
  • 描述:计算得到的相机内参矩阵。

3.distCoeffs:

  • 类型:np.ndarray
  • 形状:(5, 1) 或 (8, 1)
  • 描述:计算得到的相机畸变系数。

4.rvecs:

  • 类型:list
  • 形状:(N, 1, 3) 或 (N, 3)
  • 描述:每张图像的旋转向量。

5.tvecs:

  • 类型:list
  • 形状:(N, 1, 3) 或 (N, 3)
  • 描述:每张图像的平移向量。

2.2完整代码

import cv2
import numpy as np
import glob

# 设置棋盘格参数
chessboard_size = (11, 8)  # 棋盘格的内角点个数
square_size = 1.0  # 棋盘格每个方格的实际大小,单位可以是毫米、厘米或米

# 准备棋盘格的世界坐标系坐标(假设z=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)
objp *= square_size

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

# 获取所有棋盘格图像的路径
images = glob.glob('board_image/*.png')

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

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

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

        # 绘制角点以进行可视化
        img = cv2.drawChessboardCorners(img, chessboard_size, corners, ret)
        cv2.imshow('Chessboard Corners', img)
        cv2.waitKey(0)

cv2.destroyAllWindows()

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

# 输出相机的内参和畸变系数
print("Camera matrix:\n", mtx)
print("Distortion coefficients:\n", dist)

# 保存内参和畸变系数到文件
np.savez('camera_calibration.npz', mtx=mtx, dist=dist, rvecs=rvecs, tvecs=tvecs)

# 可选:验证标定结果
for image_path in images:
    img = cv2.imread(image_path)
    h, w = img.shape[:2]

    # 计算新的相机矩阵和有效像素区域
    # newcameramtx: 新的相机矩阵
    # roi: 有效像素区域(区域内的像素可以保证无畸变)
    newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1, (w, h))

    # 使用新的相机矩阵 undistort 方法校正畸变图像
    # mtx: 原始相机矩阵
    # dist: 畸变系数
    # newcameramtx: 新的相机矩阵
    dst = cv2.undistort(img, mtx, dist, None, newcameramtx)

    #  # 获取有效像素区域
    x, y, w, h = roi
    # 裁剪图像,只保留有效像素区域
    dst = dst[y:y + h, x:x + w]

    cv2.imshow('Undistorted Image', dst)
    cv2.waitKey(0)

cv2.destroyAllWindows()

# 加载 .npz 文件
data = np.load('camera_calibration.npz')
print('测试')
print(data['mtx'])
print(data['dist'])

三、实现效果

3.1处理图像

3.2内参与畸变系数

Camera matrix:
 [[5.78450231e+03 0.00000000e+00 8.92032508e+02]
 [0.00000000e+00 5.57232763e+03 1.07114110e+03]
 [0.00000000e+00 0.00000000e+00 1.00000000e+00]]
Distortion coefficients:
 [[ 3.13251587e-01  1.75995346e+00  1.34946542e-02 -1.23926024e-02
  -5.43635102e+01]]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1930434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

手机照片怎么改大小kb?3个压缩方法分享

手机照片怎么改大小kb?手机照片调整大小(KB)不仅是管理存储空间的实用技巧,也是适应多样化分享场景的关键。掌握调整照片大小的方法,能确保图片顺畅上传,同时保持清晰度和加载速度,提升用户体验…

Why can‘t I access GPT-4 models via API, although GPT-3.5 models work?

题意:为什么我无法通过API访问GPT-4模型,尽管GPT-3.5模型可以工作? 问题背景: Im able to use the gpt-3.5-turbo-0301 model to access the ChatGPT API, but not any of the gpt-4 models. Here is the code I am using to tes…

Linux中LVS群集应用基础—NAT模式—LVS+Apache+NFS

🏡作者主页:点击! 🐧Linux基础知识(初学):点击! 🐧Linux高级管理专栏:点击! 🔐Linux中firewalld防火墙:点击! ⏰️创作时间&…

ctfshow-web入门-php特性(web123、web125、web126)

目录 1、web123 2、web125 3、web126 1、web123 要求存在 post 传入 CTF_SHOW 和 CTF_SHOW.COM,不能存在 get 传入 fl0g。 正则匹配过滤掉了一些符号,符合则会执行 eval 函数,其中 c 来自 post 传入的 fun。 我们先说非预期解&#xff0c…

Windows搭建RTMP视频流服务器

参考了一篇文章,见文末。 博客中nginx下载地址失效,附上一个有效的地址: Index of /download/ 另外,在搭建过程中,遇到的问题总结如下: 1 两个压缩包下载解压并重命名后,需要 将nginx-rtmp…

【Linux】进程信号 --- 信号预备阶段(入门篇)

👦个人主页:Weraphael ✍🏻作者简介:目前正在学习c和算法 ✈️专栏:Linux 🐋 希望大家多多支持,咱一起进步!😁 如果文章有啥瑕疵,希望大佬指点一二 如果文章对…

PIC单片机ICSP接口电路原理图

ICSP接口电路只有五根线,依次为: VPP、VDD、VSS、PGD、PGC,它们与PIC单片机的连接如下图: 题外话单片机中的佼佼者是谁,想知道点击上方图片查看视频 为保证ICSP安全正常工作,烧写时序线PGD和PGC、烧写电压…

C语言 | Leetcode C语言题解之第237题删除链表中的节点

题目: 题解: /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/void deleteNode(struct ListNode* node) {struct ListNode * p node->next;int temp;temp node->val;node->val…

深度学习驱动智能超材料设计与应用

在深度学习与超材料融合的背景下,不仅提高了设计的效率和质量,还为实现定制化和精准化的治疗提供了可能,展现了在材料科学领域的巨大潜力。深度学习可以帮助实现超材料结构参数的优化、电磁响应的预测、拓扑结构的自动设计、相位的预测及结构…

线程控制

对线程的控制思路和进程相似,创建、等待、终止,只需要调用接口就行。但是在Linux下没有线程的概念,因为Linux的设计者认为,线程是一种轻量级的进程,毕竟创建线程只需要创建PCB。因此Linux中使用多线程必须使用第三方pt…

打破平台限制,使智能手机和平板电脑上无缝运行Windows x86/x64架构的软件和游戏的一款安卓应用

大家好,今天给大家分享一款专为Android设备设计的模拟器应用Winlator。其核心功能是能够在基于ARM架构的智能手机和平板电脑上无缝运行Windows x86/x64架构的软件和游戏。 Winlator是一款Android应用程序,它允许用户使用Wine和Box86/Box64在Android设备上…

Ubuntu的磁盘扩容遇到的问题

1.先用终端上的命令查看磁盘的使用情况 #查看磁盘空间容量的占用情况 $ df -h #查看当前文件夹中,各个文件占用磁盘空间的情况 $ du -sh* 如果容量少的话,需要尽快扩容 2.开机前的扩容 2.1 VMware 扩展磁盘空间 关闭当前客户机,在编辑虚拟…

《企业实战分享 · Druid 连接监控》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 近期刚转战 CSDN,会严格把控文章质量,绝不滥竽充数,如需交流&#xff…

华为以客户为中心的战略

2005年,伴随着国际化步伐的加快,华为重新梳理了自己的愿景、使命和发展战略,提出了以客户为中心的战略定位: 为客户服务是华为存在的唯一理由;客户需求是华为发展的原动力。质量好、服务好、运作成本低,优…

部署kafkamanager

1,检查kafka的版本 到lib下查看 libs/kafka-clients-0.11.0.3.jar kafka的版本 0.11 2,下载kafkamanager 链接: https://pan.baidu.com/s/1qYifoa4 密码:el4o 3,解压后更改该conf下conf/application.conf 中zkhosts …

VUE:跨域配置代理服务器

//在vite.config。js中,同插件配置同级进行配置server:{proxy:{"/myrequest":{//代理域名,可自行修改target:"https://m.wzj.com/",//访问服务器的目标域名changeOrigin:true,//允许跨域configure:(proxy,options) > {proxy.on(&…

Ubuntu上安装配置samba服务

Ubuntu上安装配置samba服务 在Ubuntu中安装配置samba共享服务,可以让你在网络上共享文件和打印机。以下是一个相对详细的步骤指南,介绍如何在Ubuntu上安装和配置Samba。 1. 安装Samba 首先,需要安装Samba软件包。打开终端并运行以下命令&a…

【学习笔记】无人机系统(UAS)的连接、识别和跟踪(一)-3GPP TS 23.256 技术规范概述

3GPP TS 23.256 技术规范,主要定义了3GPP系统对无人机(UAV)的连接性、身份识别、跟踪及A2X(Aircraft-to-Everything)服务的支持。 3GPP TS 23.256 技术规范: 以下是文档的核心内容总结: UAV系…

设计模式-概述*

1.代码的质量的评判 可维护性:不破坏原有代码设计以及不引入新的bug的前提下,能够快速修改或新增代码;可读性:人类能理解的代码(编程规范-命名、函数是否冗长、类是否过大等);可扩展性&#xff…

BiliBili 阴阳师主题 前端技术展示

实现效果 实现方式 纯 Html CSS 文件展示如下 下载地址 https://download.csdn.net/download/qq_43638033/89543490 部分代码解析 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"> <!-- 设置文档的字符编码…