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.rhkb.cn/news/476954.html

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

相关文章

GitLab使用操作v1.0

1.前置条件 Gitlab 项目地址&#xff1a;http://******/req Gitlab账户信息&#xff1a;例如 001/******自己的分支名称&#xff1a;例如 001-master&#xff08;注&#xff1a;master只有项目创建者有权限更新&#xff0c;我们只能更新自己分支&#xff0c;然后创建合并请求&…

机器学习阶段学习Day31

KNN分类算法 KNN算法原理 根据K个邻居样本来判断当前样本属于哪个类别&#xff1a;K个最相似邻居中大多数所属类别即为当前样本的类别。但是对于数据量巨大或者高纬度的数据样本不太合适&#xff0c;数据量大的数据样本需要进行大量计算&#xff0c;而高纬度数据计算距离不具…

【Android、IOS、Flutter、鸿蒙、ReactNative 】实现 MVP 架构

Android Studio 版本 Android Java MVP 模式 参考 模型层 model public class User {private String email;private String password;public User(String email, String password) {this.email = email;this.password = password;}public String getEmail() {return email;}…

uniapp发布android上架应用商店权限

先看效果&#xff1a; 实现原理&#xff1a; 一、利用uni.addInterceptor的拦截器&#xff0c;在一些调用系统权限前拦截&#xff0c;进行弹窗展示&#xff0c;监听确定取消实现业务逻辑。 二、弹窗是原生nativeObj进行drawRect绘制的 三、权限申请调用使用的 plus.android.…

VSCode【下载】【安装】【汉化】【配置C++环境】【运行调试】(Windows环境)

目录 一、VSCode的下载 & 安装 二、汉化 三、配置C 一、VSCode的下载 & 安装 Download Visual Studio Code - Mac, Linux, Windowshttps://code.visualstudio.com/Download 注意&#xff01;&#xff01;&#xff01;【不建议下载User版本&#xff0c;下载System版本】…

Diving into the STM32 HAL-----DAC笔记

根据所使用的系列和封装&#xff0c;STM32微控制器通常只提供一个具有一个或两个专用输出的DAC&#xff0c;除了STM32F3系列中的少数零件编号实现两个DAC&#xff0c;第一个具有两个输出&#xff0c;另一个只有一个输出。STM32G4 系列的一些较新的 MCU 甚至提供多达 5 个独立的…

OpenCV和Qt坐标系不一致问题

“ OpenCV和QT坐标系导致绘图精度下降问题。” OpenCV和Qt常用的坐标系都是笛卡尔坐标系&#xff0c;但是细微处有些不同。 01 — OpenCV坐标系 OpenCV是图像处理库&#xff0c;是以图像像素为一个坐标位置&#xff0c;即一个像素对应一个坐标&#xff0c;所以其坐标系也叫图像…

STM32完全学习——系统时钟设置

一、时钟框图的解读 首先我们知道STM32在上电初始化之后使用的是内部的HSI未经过分频直接通过SW供给给系统时钟&#xff0c;由于内部HSI存在较大的误差&#xff0c;因此我们在系统完成上电初始化&#xff0c;之后需要将STM32的时钟切换到外部HSE作为系统时钟&#xff0c;那么我…

Java NIO 核心知识总结

在学习 NIO 之前&#xff0c;需要先了解一下计算机 I/O 模型的基础理论知识。还不了解的话&#xff0c;可以参考我写的这篇文章&#xff1a;Java IO 模型详解。 一、NIO 简介 在传统的 Java I/O 模型&#xff08;BIO&#xff09;中&#xff0c;I/O 操作是以阻塞的方式进行的。…

前端-react(class组件和Hooks)

文章主要以Hooks为主,部分涉及class组件方法进行对比 一.了解react 1.管理组件的方式 在React中&#xff0c;有两种主要的方式来管理组件的状态和生命周期&#xff1a;Class 组件和 Hooks。 Class 组件&#xff1a; Class 组件是 React 最早引入的方式&#xff0c;它是基于…

python爬虫-下载高德地图区域(省,市,区)

python爬虫&#xff0c;用于下载&#xff1a;https://datav.aliyun.com/portal/school/atlas/area_selector 的中国地图及其下钻省市区的json文件。在echarts或者leaflet展示。 可能会少几个市区的full.json数据&#xff0c;api的xml调不通&#xff0c;可以手动去 https://data…

uni-app 修改复选框checkbox选中后背景和字体颜色

编写css&#xff08;注意&#xff1a;这个样式必须写在App.vue里&#xff09; /* 复选框 */ /* 复选框-圆角 */ checkbox.checkbox-round .wx-checkbox-input, checkbox.checkbox-round .uni-checkbox-input {border-radius: 100rpx; } /* 复选框-背景颜色 */ checkbox.checkb…

MacOS下的Opencv3.4.16的编译

前言 MacOS下编译opencv还是有点麻烦的。 1、Opencv3.4.16的下载 注意&#xff0c;我们使用的是Mac&#xff0c;所以ios pack并不能使用。 如何嫌官网上下载比较慢的话&#xff0c;可以考虑在csdn网站上下载&#xff0c;应该也是可以找到的。 2、cmake的下载 官网的链接&…

内外网交换过程中可能遇到的安全风险有哪些?

在数字化时代&#xff0c;企业内外网之间的数据交换变得日益频繁。然而&#xff0c;这一过程中的安全风险和效率问题也日益凸显。我们将探讨内外网交换可能遇到的安全风险&#xff0c;并介绍镭速内外网交换系统如何有效应对这些挑战。 内外网交换过程中的五大安全风险 数据泄露…

Redis的过期删除策略和内存淘汰机制以及如何保证双写的一致性

Redis的过期删除策略和内存淘汰机制以及如何保证双写的一致性 过期删除策略内存淘汰机制怎么保证redis双写的一致性?更新策略先删除缓存后更新数据库先更新数据库后删除缓存如何选择&#xff1f;如何保证先更新数据库后删除缓存的线程安全问题&#xff1f; 过期删除策略 为了…

GESP2023年9月认证C++四级( 第三部分编程题(1-2))

编程题1&#xff08;string&#xff09;参考程序&#xff1a; #include <iostream> using namespace std; long long hex10(string num,int b) {//int i;long long res0;for(i0;i<num.size();i) if(num[i]>0&&num[i]<9)resres*bnum[i]-0;else //如果nu…

VSCode汉化教程【简洁易懂】

我们安装完成后默认是英文界面。 找到插件选项卡&#xff0c;搜索“Chinese”&#xff0c;找到简体&#xff08;更具你的需要&#xff09;&#xff08;Microsoft提供&#xff09;Install。 安装完成后选择Change Language and Restart。

java学习-集合

为什么有集合&#xff1f; 自动扩容 数组&#xff1a;长度固定&#xff0c;可以存基本数据类型和引用数据类型 集合&#xff1a;长度可变&#xff0c;可以存引用数据类型&#xff0c;基本数据类型的话需要包装类 ArrayList public class studentTest {public static void m…

MATLAB GUI设计(基础)

一、目的和要求 1、熟悉和掌握MATLAB GUI的基本控件的使用及属性设置。 2、熟悉和掌握通过GUIDE创建MATLAB GUI的方法。 3、熟悉和掌握MATLAB GUI的菜单、对话框及文件管理框的设计。 4、熟悉和掌握MATLAB GUI的M文件编写。 5、了解通过程序创建MATLAB GUI的方法。 二、内…

【工具变量】中国省级及地级市保障性住房数据集(2010-2023年)

一、测算方式&#xff1a;参考顶刊《世界经济》蔡庆丰&#xff08;2024&#xff09;老师的研究&#xff0c;具体而言&#xff0c;本文将土地用途为经济适用住房用地、廉租住房用地、公共租赁住房用地、共有产权住房用 地等类型的土地定义为具有保障性住房用途的土地。根据具有保…