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

news2024/11/24 2:32:59
  • 操作系统: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 和 objPoints
            imgPoints.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.coloradmin.cn/o/2246376.html

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

相关文章

Redis五大基本类型——Set集合命令详解(命令用法详解+思维导图详解)

目录 一、Set集合类型介绍 二、常见命令 1、SADD 2、SMEMBERS 3、SISMEMBER 4、SCARD 5、SRANDMEMBER 6、SPOP 7、SMOVE 8、SREM ​编辑 9、集合间操作 &#xff08;1&#xff09;SINTER &#xff08;2&#xff09;SINTERSTORE &#xff08;3&#xff09;SUNION…

CCE-基础

背景&#xff1a; 虚拟化产生解决物理机资源浪费问题&#xff0c;云计算出现实现虚拟化资源调度和管理&#xff0c;容器出现继续压榨虚拟化技术产生的资源浪费&#xff0c;用命名空间隔离&#xff08;namespace&#xff09; 灰度升级&#xff08;升级中不影响业务&#xff09…

Chrome离线安装包下载

1、问Chrome的官网&#xff1a;https://www.google.cn/chrome/ 直接下载的是在线安装包&#xff0c;安装需要联网。 2、如果需要在无法联网的设备上安装Chrome&#xff0c;需要在上面的地址后面加上?standalone1。 Chrome离线安装包下载地址&#xff1a;https://www.google.c…

二进制 分析工具:Radare2、r2frida、Binutils、file、string、as、nm、ldd、objdump、readelf、strip

1、二进制 分析工具 工欲善其事&#xff0c;必先利其器&#xff0c;在二进制安全的学习中&#xff0c;​使用工具尤为重要。遇到一个不熟悉的文件时&#xff0c; 首先要确定 "这是什么类型的文件"&#xff0c;回答这个问题的首要原则是&#xff0c;绝不要根据文件的扩…

快速图像识别:落叶植物叶片分类

1.背景意义 研究背景与意义 随着全球生态环境的变化&#xff0c;植物的多样性及其在生态系统中的重要性日益受到关注。植物叶片的分类不仅是植物学研究的基础&#xff0c;也是生态监测、农业管理和生物多样性保护的重要环节。传统的植物分类方法依赖于人工观察和专家知识&…

Chrome 浏览器 131 版本新特性

Chrome 浏览器 131 版本新特性 一、Chrome 浏览器 131 版本更新 1. 在 iOS 上使用 Google Lens 搜索 自 Chrome 126 版本以来&#xff0c;用户可以通过 Google Lens 搜索屏幕上看到的任何图片或文字。 要使用此功能&#xff0c;请访问网站&#xff0c;并点击聚焦时出现在地…

Windows系统编程 - 注册表

文章目录 前言注册表介绍打开和关闭注册表RegOpenKeyExRegCloseKey测试案例 创建删除子键RegCreateKeyEx创建子键RegDeleteKey删除子键 写入删除键值RegQueryValueExRegSetValueExRegDeleteValue测试案例 子键和项的枚举RegEnumKeyExRegEnumValueRegQueryInfoKey测试案例 总结 …

Jenkins + gitee 自动触发项目拉取部署(Webhook配置)

目录 前言 Generic Webhook Trigger 插件 下载插件 ​编辑 配置WebHook 生成tocken 总结 前言 前文简单介绍了Jenkins环境搭建&#xff0c;本文主要来介绍一下如何使用 WebHook 触发自动拉取构建项目&#xff1b; Generic Webhook Trigger 插件 实现代码推送后&#xff0c;触…

Failed to start Docker Application Container Engine

说明&#xff1a; 1&#xff09;访问应用业务&#xff0c;读取不到数据&#xff0c;show databases;查看数据库报错 2&#xff09;重启docker服务&#xff0c;服务启动失败&#xff0c;查看日志报错如下图所示 3&#xff09;报错信息&#xff1a;chmod /data/docker: read-only…

1、HCIP之RSTP协议与STP相关安全配置

目录 RSTP—快速生成树协议 STP STP的缺点&#xff1a; STP的选举&#xff08;Listening状态中&#xff09;&#xff1a; RSTP P/A&#xff08;提议/同意&#xff09;机制 同步机制&#xff1a; 边缘端口的配置&#xff1a; RSTP的端口角色划分&#xff1a; ensp模拟…

Kafka 生产者优化与数据处理经验

Kafka&#xff1a;分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析&#xff1a;从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析&#xff1a…

Hello-Go

Hello-Go 环境变量 GOPATH 和 GOROOT &#xff1a;不同于其他语言&#xff0c;go中没有项目的说法&#xff0c;只有包&#xff0c;其中有两个重要的路径&#xff0c;GOROOT 和 GOPATH Go开发相关的环境变量如下&#xff1a; GOROOT&#xff1a;GOROOT就是Go的安装目录&…

android 实现答题功能

一、效果 二、实现思路 1、界面实现 实现起来其实不难&#xff0c;首先我们可以看到&#xff0c;界面是由答题进度、题目、选项ABCD组成&#xff0c;现在就是要考虑实现方式&#xff0c;答题进度可以使用Textviewprogressbar实现&#xff0c;题目直接使用Textview&#xff0c;…

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

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

React(二)

文章目录 项目地址七、数据流7.1 子组件传递数据给父组件7.1.1 方式一:給父设置回调函数,传递给子7.1.2 方式二:直接将父的setState传递给子7.2 给props传递jsx7.2.1 方式一:直接传递组件给子类7.2.2 方式二:传递函数给子组件7.3 props类型验证7.4 props的多层传递7.5 cla…

浅谈丨功能安全测试,汽车的守护者

随着新能源汽车迅猛的发展&#xff0c;各类车型频频面世&#xff0c;同时辅助驾驶/自动驾驶等智驾功能也在不断迭代&#xff0c;使得整个汽车系统的复杂性越来越高&#xff0c;最终导致消费者不得不对如今的汽车质量和安全性提出质疑。 如何打破质疑&#xff1f; 那就不得不搬…

bridge-multicast-igmpsnooping

# 1.topo # 2.创建命名空间 ip netns add ns0 ip netns add ns1 ip netns add ns2 ip netns add ns3 # 3.创建veth设备 ip link add ns0-veth0 type veth peer name hn0-veth0 ip link add ns1-veth0 type veth peer name hn1-veth0 ip link add ns2-veth0 type veth pe…

密码学11

概论 计算机安全的最核心三个关键目标&#xff08;指标&#xff09;/为&#xff1a;保密性 Confidentiality、完整性 Integrity、可用性 Availability &#xff0c;三者称为 CIA三元组 数据保密性&#xff1a;确保隐私或是秘密信息不向非授权者泄漏&#xff0c;也不被非授权者使…

MIT 6.S081 | 操作系统 | Lab1: Xv6 and Unix utilities

Lab1: Xv6 and Unix utilities 文章目录 Lab1: Xv6 and Unix utilities实验任务1.启动XV6(easy)2.Sleep(easy)-练手的&#xff0c;就是熟悉一下怎么在xv6项目中加.c文件&#xff0c;生成可执行程序并进行测试的1.解析rm.c2.argc 如何被赋值3.Sleep代码4.makefile编辑5.通过make…

在SpringBoot项目中集成MongoDB

文章目录 1. 准备工作2. 在SpringBoot项目中集成MongoDB2.1 引入依赖2.2 编写配置文件2.3 实体类 3. 测试4. 文档操作4.1 插入操作4.1.1 单次插入4.1.2 批量插入 4.2 查询操作4.2.1 根据id查询4.2.2 根据特定条件查询4.2.3 正则查询4.2.4 查询所有文档4.2.5 排序后返回 4.3 删除…