OpenCV相机标定与3D重建(3)校正鱼眼镜头畸变的函数calibrate()的使用

  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

cv::fisheye::calibrate 函数是 OpenCV 中用于校正鱼眼镜头畸变的一个重要函数。该函数通过一系列棋盘格标定板的图像来计算相机的内参矩阵和畸变系数。

函数原型

double cv::fisheye::calibrate	
(InputArrayOfArrays 	objectPoints,InputArrayOfArrays 	imagePoints,const Size & 	image_size,InputOutputArray 	K,InputOutputArray 	D,OutputArrayOfArrays 	rvecs,OutputArrayOfArrays 	tvecs,int 	flags = 0,TermCriteria 	criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 100, DBL_EPSILON) 
)	

参数

  • 参数objectPoints:标定图案坐标空间中标定图案点的向量的向量。
  • 参数imagePoints:标定图案点投影的向量的向量。对于每个 i,imagePoints.size() 和 objectPoints.size() 以及 imagePoints[i].size() 必须等于 objectPoints[i].size()。
  • 参数image_size:仅用于初始化相机内参矩阵的图像尺寸。
  • 参数K:输出 3x3 浮点型相机内参矩阵 K = [ f x 0 c x 0 f y c y 0 0 1 ] K = \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} K= fx000fy0cxcy1 。如果指定了 fisheye::CALIB_USE_INTRINSIC_GUESS,则 fx, fy, cx, cy 中的一些或全部必须在调用函数前初始化。
  • 参数D:输出的畸变系数向量 D = [ k 1 k 2 k 3 k 4 ] D = \begin{bmatrix} k_1 & k_2 & k_3 & k_4 \end{bmatrix} D=[k1k2k3k4]
  • 参数rvecs:输出的旋转向量向量(见 Rodrigues),每个元素是一个 3x1 向量,表示每个图案视图的旋转。每个第 k 个旋转向量与对应的第 k 个平移向量(见下一个输出参数描述)一起,将标定板从模型坐标空间(在其中指定物体点)带到世界坐标空间,即标定板在第 k 个图案视图中的真实位置(k=0…M-1)。
  • 参数tvecs:输出的平移向量向量,每个元素是一个 3x1 向量,表示每个图案视图的平移。
  • 参数flags:不同的标志,可以是零或以下值的组合:
    • fisheye::CALIB_USE_INTRINSIC_GUESS:cameraMatrix 包含有效的初始值 fx, fy, cx, cy,这些值将进一步优化。否则,(cx, cy) 最初设置为图像中心(使用 imageSize),焦距以最小二乘法计算。
    • fisheye::CALIB_RECOMPUTE_EXTRINSIC:每次内在参数优化迭代后,外在参数将重新计算。
    • fisheye::CALIB_CHECK_COND:函数将检查条件数的有效性。
    • fisheye::CALIB_FIX_SKEW:斜率系数(alpha)设置为零并保持不变。
    • fisheye::CALIB_FIX_K1 到 fisheye::CALIB_FIX_K4:选定的畸变系数设置为零并保持不变。
    • fisheye::CALIB_FIX_PRINCIPAL_POINT:主点在全局优化过程中不改变。它保持在中心或在 fisheye::CALIB_USE_INTRINSIC_GUESS 设置时指定的不同位置。
    • fisheye::CALIB_FIX_FOCAL_LENGTH:焦距在全局优化过程中不改变。它是 max(width, height)/π 或者当
    • fisheye::CALIB_USE_INTRINSIC_GUESS 设置时提供的 fx, fy。
  • criteria:迭代优化算法的终止条件。

代码示例


#include <iostream>
#include <opencv2/calib3d.hpp>
#include <opencv2/opencv.hpp>
#include <string>
#include <vector>using namespace cv;
using namespace std;int main( int argc, char** argv )
{// 棋盘格尺寸(内部角点数)Size boardSize( 5, 8 );// 存储棋盘格角点的世界坐标vector< Point3f > objp;for ( int i = 0; i < boardSize.height; ++i ){for ( int j = 0; j < boardSize.width; ++j ){objp.push_back( Point3f( j, i, 0 ) );}}// 存储所有图像中的棋盘格角点的像素坐标vector< vector< Point2f > > imgPoints;// 存储所有图像中棋盘格角点的世界坐标vector< vector< Point3f > > objPoints;// 读取图像文件列表vector< String > imageNames;glob( "/media/dingxin/data/study/OpenCV/sources/images/chessboard.png", imageNames, false );if ( imageNames.empty() ){std::cout << "No images found at the specified path." << std::endl;return -1;}Mat img, gray;for ( const auto& imageName : imageNames ){img = imread( imageName, IMREAD_COLOR );if ( img.empty() ){std::cout << "Could not open or find the image: " << imageName << std::endl;continue;}cvtColor( img, gray, COLOR_BGR2GRAY );// 查找棋盘格角点vector< Point2f > corners;bool found = findChessboardCorners( gray, boardSize, corners, CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CALIB_CB_FAST_CHECK );if ( found ){// 亚像素精确定位cornerSubPix( gray, corners, Size( 11, 11 ), Size( -1, -1 ), TermCriteria( TermCriteria::EPS + TermCriteria::MAX_ITER, 30, 0.1 ) );// 添加角点到 imgPoints 和 objPointsimgPoints.push_back( corners );objPoints.push_back( objp );// 绘制角点drawChessboardCorners( img, boardSize, corners, found );imshow( "Found Corners", img );waitKey( 500 );}else{std::cout << "Could not find chessboard corners in image: " << imageName << std::endl;}}// 检查是否有足够的图像用于校准if ( imgPoints.empty() ){std::cout << "No valid images found for calibration." << std::endl;return -1;}// 相机内参矩阵Mat K = Mat::eye( 3, 3, CV_64F );// 畸变系数Mat D = Mat::zeros( 4, 1, CV_64F );// 终止条件TermCriteria criteria( TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON );// 校准int flags  = cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC + cv::fisheye::CALIB_FIX_SKEW + cv::fisheye::CALIB_CHECK_COND;double rms = cv::fisheye::calibrate( objPoints, imgPoints, gray.size(), K, D, noArray(), noArray(), flags, criteria );cout << "RMS re-projection error: " << rms << endl;cout << "Camera matrix:\n" << K << endl;cout << "Distortion coefficients:\n" << D << endl;// 保存结果FileStorage fs( "calibration_result.yml", FileStorage::WRITE );fs << "camera_matrix" << K;fs << "dist_coeffs" << D;fs.release();cv::waitKey( 0 );return 0;
}

运行结果

在这里插入图片描述
终端输出:

RMS re-projection error: 0.0538752
Camera matrix:
[125280.3440762279, 0, 224.5000000010562;0, 125280.3438483639, 149.4999999998818;0, 0, 1]
Distortion coefficients:
[-582.4113543586071;116.5218245736505;-11.04383019115448;0.5796488453961863]

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

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

相关文章

【过程控制系统】第6章 串级控制系统

目录 6. l 串级控制系统的概念 6.1.2 串级控制系统的组成 6.l.3 串级控制系统的工作过程 6.2 串级控制系统的分析 6.2.1 增强系统的抗干扰能力 6.2.2 改善对象的动态特性 6.2.3 对负荷变化有一定的自适应能力 6.3 串级控制系统的设计 6.3.1 副回路的选择 2.串级系…

24/11/22 项目拆解 艺术风格转移

我们有时候想把两种艺术风格整合&#xff0c;创造更具艺术特色的艺术品&#xff0c;人很难办到&#xff0c;但是人工智能可以,比如下面将艺术画的风格转移到照片上。 我们先来初步了解一下实现上述功能的数学原理 所谓艺术风格&#xff0c;其实就是边缘&#xff0c;颜色&#…

Unity图形学之CubeMap立方体贴图

1.CubeMap&#xff1a;有六个面的贴图组成 2. 假反射&#xff1a;反射天空盒子 &#xff08;1&#xff09;正常UV采样&#xff1a; &#xff08;2&#xff09;Cube的采样&#xff1a;利用反射角采样&#xff0c;反射角X和Cube的交点采样 Shader "Custom/TestReflect"…

LLM Inference Unveiled

题目&#xff1a;LLM Inference Unveiled: Survey and Roofline Model Insights 链接&#xff1a;https://arxiv.org/abs/2402.16363 这也是一篇推理加速的综述&#xff0c;重点关注一下它的组织结构吧&#xff0c;也就是它对推理加速方法的分类 论文给的全文结构图&#xff…

Cesium的ClearCommand的流程

ClearCommand是在每帧渲染前可以将显存的一些状态置为初始值&#xff0c;就如同把擦黑板。当然也包括在绘制过程中擦掉部分的数据&#xff0c;就如同画家在开始绘制的时候会画导览线&#xff08;如透视线&#xff09;&#xff0c;轮廓出来后这些导览线就会被擦除。 我画了一个…

【Linux】重定向,dup

目录 文件描述符分配规则 重定向 dup ​编辑 输出重定向 追加重定向 输入重定向。 重定向会影响后面的程序替换吗&#xff1f; 1号文件和2号文件 2号文件输出重定向 下标之间的重定向 文件描述符分配规则 重定向 把显示器文件关闭后&#xff0c;本来应该写给显示器…

大语言模型---梯度的简单介绍;梯度的定义;梯度计算的方法

1. 梯度介绍 如果我们在一座山上&#xff08;一个山的坡度有很多&#xff0c;陡峭的&#xff0c;平缓的&#xff09;&#xff0c;想要从山顶下山。而梯度就像告诉我们如何沿着最陡的下坡路线走&#xff0c;以尽快到达山脚&#xff08;最低点&#xff09;。 2. 梯度的定义 梯度…

【JAVA】一次操蛋的nginx镜像之旅

一、前言 由于我们的项目中使用到了nginx&#xff0c;同时我们的nginx是通过docker镜像进行安装的&#xff0c;由于nginx出现了问题&#xff0c;需要重新安装。于是。。。 二、通过docker进行安装 docker pull nginx:latest 1.5.2 脚本文件 在/home/docker/script路径下创…

ubuntu24挂载硬盘记录

1、显示硬盘及所属分区情况。在终端窗口中输入如下命令&#xff1a; sudo fdisk -l 找到自己硬盘的分区 我的地址/dev/sda 2、显示硬盘及所属分区情况。在终端窗口中输入如下命令&#xff0c;格式化自己硬盘&#xff1a; sudo mkfs -t ext4 /dev/sda 3、在终端窗口中输入如下…

业务架构、数据架构、应用架构和技术架构

TOGAF(The Open Group Architecture Framework)是一个广泛应用的企业架构框架&#xff0c;旨在帮助组织高效地进行架构设计和管理。 TOGAF 的核心就是由我们熟知的四大架构领域组成:业务架构、数据架构、应用架构和技术架构。 企业数字化架构设计中的最常见要素是4A 架构。 4…

苹果Siri将搭载大型语言模型,近屿智能抢占AIGC大模型人才培养高地

据媒体报道&#xff0c;苹果公司正在研发一款全新升级、更加智能且对话能力显著提升的Siri&#xff0c;意在超越OpenAI的ChatGPT及其他语音服务。 报道指出&#xff0c;新一代Siri将搭载更为先进的大型语言模型&#xff08;LLM&#xff09;&#xff0c;苹果期望其能够进行连续…

【1.4 Getting Started--->Support Matrix】

主页&#xff1a;支持矩阵 这些支持矩阵概述了 TensorRT API、解析器和层支持的平台、特性和硬件功能。 Support Matrix Abstract 这些支持矩阵概述了 TensorRT API、解析器和层所支持的平台、功能和硬件功能。 有关之前发布的 TensorRT 文档&#xff0c;请参阅 TensorRT 档…

WPF中如何让Textbox显示为一条直线

由于Textbox直接使用是一条直线 设置如下代码 可以让Textbox变为直线输入 <Style TargetType"TextBox"x:Key"UsernameTextBoxStyle"><Setter Property"Template"><Setter.Value><ControlTemplate TargetType"{x:Typ…

Mac 修改默认jdk版本

当前会话生效 这里演示将 Java 17 版本降低到 Java 8 查看已安装的 Java 版本&#xff1a; 在终端&#xff08;Terminal&#xff09;中运行以下命令&#xff0c;查看已安装的 Java 版本列表 /usr/libexec/java_home -V设置默认 Java 版本&#xff1a; 找到 Java 8 的安装路…

K8S + Jenkins 做CICD

前言 这里会做整体CICD的思路和流程的介绍&#xff0c;会给出核心的Jenkins pipeline脚本&#xff0c;最后会演示一下 实验/实操 结果 由于整体内容较多&#xff0c;所以不打算在这里做每一步的详细演示 - 本文仅作自己的实操记录和日后回顾用 要看保姆式教学的可以划走了&…

使用 前端技术 创建 QR 码生成器 API1

前言 QR码&#xff08;Quick Response Code&#xff09;是一种二维码&#xff0c;于1994年开发。它能快速存储和识别数据&#xff0c;包含黑白方块图案&#xff0c;常用于扫描获取信息。QR码具有高容错性和快速读取的优点&#xff0c;广泛应用于广告、支付、物流等领域。通过扫…

基于Java Springboot高校工作室管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

【读书】复杂性意义结构框架——Cynefin框架

Cynefin框架 《代码大全》的作者史蒂夫麦克康奈尔&#xff08;Steve McConnell&#xff09;在《卓有成效的敏捷》这本书里&#xff0c;探讨了用于理解不确定性和复杂性的Cynefin框架。 Cynefin框架是戴维斯诺登&#xff08;David Snowden&#xff09;20世纪90年代的在IBM时创…

ZYNQ-7020嵌入式系统学习笔记(1)——使用ARM核配置UART发送Helloworld

本工程实现调用ZYNQ-7000的内部ARM处理器&#xff0c;通过UART给电脑发送字符串。 硬件&#xff1a;正点原子领航者-7020 开发平台&#xff1a;Vivado 2018、 SDK 1 Vivado部分操作 1.1 新建工程 设置工程名&#xff0c;选择芯片型号。 1.2 添加和配置PS IP 点击IP INTEGR…

全面击破工程级复杂缓存难题

目录 一、走进业务中的缓存 &#xff08;一&#xff09;本地缓存 &#xff08;二&#xff09;分布式缓存 二、缓存更新模式分析 &#xff08;一&#xff09;Cache Aside Pattern&#xff08;旁路缓存模式&#xff09; 读操作流程 写操作流程 流程问题思考 问题1&#…