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

opencv_c++学习(二十七)

一、单目相机模型

在这里插入图片描述
上图为针孔相机成像原理,蓝色坐标中的O即为镜头光心。成像原理与小孔成像相同。
在这里插入图片描述
单目相机映射关系如下:
在这里插入图片描述
将上式进行变换,就可以从三位空间映射到2维平面的公式。
在这里插入图片描述
相机的畸变公式如下:
在这里插入图片描述

二、模型投影函数

void cv:projectPoints ( InputArray objectPoints, InputArray rvec, InputArray tvec, InputArray cameraMatrix,InputArray distCoeffs,outputArray imagePolints, jacobian =, OutputArray naArray(), double aspectRatio = 0)

objectPoints:世界坐标系中3D点的三维坐标。
rvec:世界坐标系变换到相机坐标系的旋转向量。
tvec:世界坐标系变换到相机坐标系的平移向量。
cameraMatrix:相机的内参矩阵。
distCoeffs:相机的畸变系数矩阵。
imagcPoints:三维坐标点在像素坐标系中估计的坐标。
jacobian:可选输出的雅可比矩阵。
aspectRatio:是否固定“宽高比”参数标志。
本节应用案例如下:

int main() {//输入计算的内参矩阵和畸变矩阵(在相机厂家说明或者标定获得)Mat cameraMatrix = (Mat_<float>(3, 3) << 532.016297, 0, 332.172519,0, 531.565159, 233.388075,0, 0, 1);Mat distCoeffs = (Mat_<float>(1, 5) << -0.285188, 0.080097, 0.001274,0.002415, 0.106579);//图像相机坐标系与世界坐标系之间的关系Mat rvec = (Mat_<float>(1, 3) << -1.977853, -2.002220, 0.130029);Mat tvec = (Mat_<float>(1, 3) << -26.88155, -42.79936, 159.19703);//生成第一张图像中内角点的三位世界坐标Size boardSize = Size(9,6);//棋盘格每个方格的真实尺寸Size squareSize = Size(10, 10);vector<Point3f> PointSets;for (int j = 0; j < boardSize.height; j++){for (int k = 0; k < boardSize.width; k++){Point3f realPoint;//假设标定板为世界坐标系的Z平面,及z=0realPoint.x = j * squareSize.width;realPoint.y = k * squareSize.height;realPoint.z = 0;PointSets.push_back(realPoint);}}//根据三维坐标和相机与世界坐标系时间的关系估计内角点像素坐标vector<Point2f> imagePoints;projectPoints(PointSets, rvec, tvec, cameraMatrix, distCoeffs, imagePoints);for (int i = 0; i < imagePoints.size(); i++){cout << imagePoints[i] << endl;}waitKey(0);return 0;}

三、单目相机标定

标定原理:
在这里插入图片描述
从上图中可以看出,相机坐标系可以通过世界坐标系进行平移变换来得到。具体的变换矩阵如相机坐标系右侧的公式。
标定板的图例如下:
在这里插入图片描述
上图中为两种类型的标定板,左侧为常用标定板,在提取的时候是内角点。而右侧标定板中不存在内角点,所以我们提取的是每个圆的中心点。
内角点提取函数如下:

bool cv:.findChessboardCorners ( InputArray image, Size patternSize, OutputArray corners, int flags = CALIB_CB_ADAPTIVE_THRESH+CALIB_CB_NORNALIZE_IPAGE)

image:含有棋盘标定板的图像,图像必须是CV_8U的灰度图像或者彩色图像。
patternSize:图像中棋盘内角点行数和列数
corners:检测到的角点坐标
flags:检测角点方式的标志
圆形标定板中心提取:

bool cv::findCirclesGrid ( InputArray image, Size patternSize, OutputArray centers, int flags, const Ptr< FeatureDetector > & blolbDetector, const CirclesGridFinderParameters & parameters)

image:输入含有圆形网格的图像,图像必须是CV_8U的灰度图像或者彩色图像。
patternSize:图像中每行和每列圆形的数目。
corners:输出的圆形中心坐标。
flags:检测圆心的操作标志。
blobDetector:在浅色背景中寻找黑色圆形斑点的特征探测器。
角点位置优化函数:

bool cv.find4QuadCornerSubpix ( InputArray img, InputOutputArray corners, size region_size)

img:计算出内角点的图像。
patternSize:内角点坐标。
corners:优化坐标时考虑的邻域范围。

绘制内角点提取的结果:

void cv::drawChessboardCorners ( InputOutputArray image, size patternSize, InputArray corners, bool patternWasFound)

image:需要绘制角点的目标图像,必须是CU_8U的彩色图像。patternSize:标定板每行和每列角点的数目。
corners:检测到的角点坐标数组。
pattern WasFound:是否显示找到完成的标定板标志。

相机标定函数:

double cv::calibrateCamera ( InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints,Size imageSize, InputOutputArray cameraMatrix, InputoutputArray distCoeffs, OutputArrayOfArrays     rvecs, OutputArrayOfArrays tvecs,int flags = 0, TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS,30,DBL_EPSILON)

objectPoints:棋盘格内角点的三维坐标。
imagePoints:棋盘格内角点在图像中的二维坐标。
imageSize:图像的像素尺寸大小。
cameraMatrix:相机的内参矩阵。
distCoeffs:相机的畸变系数矩阵。
rvecs:相机坐标系与世界坐标系之间的旋转向量。
tvecs:相机坐标系与世界坐标系之间的平移向量。
flags:选择标定算法的标志。
本节应用案例如下:
本案例中采用了两张标定板的提取图像:
在这里插入图片描述
在这里插入图片描述
并将两个图片的路径存放到ca.txt文件中
在这里插入图片描述

int main() {//读取图像vector<Mat>imgs;string imgName;//读取存放图片路径的txt文件ifstream fin("ca.txt");//挨个读取图片while(getline(fin, imgName)){Mat img = imread(imgName);imgs.push_back(img);}//方格标定板内角点的数目(行,列)Size board_size = Size(9, 6);//存放内角点坐标vector<vector<Point2f>> imgsPoints;//开始内角点提取for (int i = 0; i < imgs.size(); i++){Mat img1 = imgs[i];Mat gray1;cvtColor(img1, gray1, COLOR_BGR2GRAY);vector<Point2f> img1_points;//计算标定板的角点findChessboardCorners(gray1, board_size, img1_points);//细化方格标定板角点坐标find4QuadCornerSubpix(gray1, img1_points, Size(5, 5));bool pattern = true;drawChessboardCorners(img1, board_size, img1_points, pattern);namedWindow("img1", WINDOW_NORMAL);imshow("img1", img1);waitKey(0);imgsPoints.push_back(img1_points);}//生成每个内角点的空间坐标Size squareSize = Size(10, 10);vector<vector<Point3f>> objectPoints;for (int i = 0; i < imgsPoints.size(); i++){vector<Point3f> tempPointSet;for (int j = 0; j < board_size.height; j++){for (int k = 0; k < board_size.width; k++){Point3f realPoint;//设标定板为世界坐标系的z平面,即z=0realPoint.x = j * squareSize.width;realPoint.y = k * squareSize.height;realPoint.z = 0;tempPointSet.push_back(realPoint);}}objectPoints.push_back(tempPointSet);}//图像尺寸Size imageSize;imageSize.width = imgs[0].cols;imageSize.height = imgs[0].rows;//摄像机内参数矩阵Mat cameraMatrix = Mat(3, 3, CV_32FC1, Scalar::all(0));//摄像机的5个畸变系数:k1,k2,p1,p2,k3Mat distCoeffs = Mat(1, 5, CV_32FC1, Scalar::all(0));//每幅图像的旋转向量、平移量vector<Mat>  rvecs, tvecs;calibrateCamera(objectPoints, imgsPoints, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs, 0);cout << "相机的内参矩阵:" << cameraMatrix << endl;cout << "相机畸变系数:" << distCoeffs << endl;waitKey(0);return 0;
}

最终的运行结果如下图:
在这里插入图片描述
这里只放一张图像。最终的输出结果为:

相机的内参矩阵:[120.8643306554273, 0, 94.55565247064737;0, 119.979406894919, 55.48571212317609;0, 0, 1]
相机畸变系数:[-0.5559208449775317, 3.15840209023594, -0.001816753642197531, -0.01817901488786, -7.629569308066959]

四、图像矫正

在这里插入图片描述
如上图(左)可以看出,相机采集的数据造成了一定的畸变,尤其是在边缘部分。

去畸变函数:

void cv::undistort ( InputArray src, OutputArray dst, InputArray cameraMatrix, InputArray  distCoeffs, InputArray newCameraMatrix = noArray())

src:含有畸变的输入图像。
dst:去畸变后的输出图像,与输入图像具有相同的尺寸和数据类型。
cameraMatrix:相机内参矩阵(上节中相机标定获得)。
distCoeffis:相机的畸变矩阵,根据近似模型不同,参数数量可以为4、5、8、12或者14,如果是空矩阵表示没有畸变。
newCameraMatrix:畸变图像的相机内参矩阵,一般情况下与第三个参数相同或者使用默认值。
本节应用案例如下:

//用undiststort()函数直接计算校正图像
void undist(vector<Mat> imgs, //原有图像向量Mat cameraMatrix, //计算得到的相机内存Mat distCoeffs, //计算得到的相机畸变系数vector<Mat> &undistImgs //校正后的输出图像
)
{for (int i = 0; i < imgs.size(); i++){Mat undisImg;undistort(imgs[i], undistImgs, cameraMatrix, distCoeffs);undistImgs.push_back(undisImg);}
}int main() {//读取图像vector<Mat>imgs;string imgName;//读取存放图片路径的txt文件ifstream fin("ca.txt");//挨个读取图片while (getline(fin, imgName)){Mat img = imread(imgName);imgs.push_back(img);}//输入计算的内参矩阵和畸变矩阵(在相机厂家说明或者标定获得)Mat cameraMatrix = (Mat_<float>(3, 3) << 120.8643306554273, 0, 94.55565247064737,0, 119.979406894919, 55.48571212317609,0, 0, 1);Mat distCoeffs = (Mat_<float>(1, 5) << -0.5559208449775317, 3.15840209023594, -0.001816753642197531, -0.01817901488786, -7.629569308066959);//去畸变图像存放变量vector<Mat> undistImags;Size imageSize;imageSize.width = imgs[0].cols;imageSize.height = imgs[0].rows;undist(imgs, cameraMatrix, distCoeffs, undistImags);//显示校正后的图像for (int i = 0; i < imgs.size(); i++){string windowNumber = to_string(i);imshow("矫正后的图像" + windowNumber, undistImags[i]);waitKey(0);destroyWindow("矫正后的图像" + windowNumber);}waitKey(0);return 0;
}

相关文章:

opencv_c++学习(二十七)

一、单目相机模型 上图为针孔相机成像原理&#xff0c;蓝色坐标中的O即为镜头光心。成像原理与小孔成像相同。 单目相机映射关系如下&#xff1a; 将上式进行变换&#xff0c;就可以从三位空间映射到2维平面的公式。 相机的畸变公式如下&#xff1a; 二、模型投影函数 vo…...

探查chatGPT插件:Outschool,resume,webhooks

引言 在我们的日常工作和学习中&#xff0c;插件扮演着重要的角色。它们可以帮助我们提高效率&#xff0c;简化复杂的任务。在这篇文章中&#xff0c;我将介绍三个非常有用的插件&#xff1a;Outschool&#xff0c;resume&#xff0c;和webhooks&#xff0c;并通过具体的例子来…...

【学习笔记】Unity基础(七)【uGUI基础、利用render Texture实现小地图功能】

目录 一 Canvas1.1 三种Render Space渲染空间 screen1.2 canvas scaler画布缩放器1.3sprite1.4 sprite packer1.5 unity目录1.6 RuleTile Tilemap1.7 sprite packer1.8 sorting layer 二 rect transform2.1 pivot 中轴 中心点2.2 anchor 锚点2.3 uGUI源代码 三 EventSystem3.1 …...

yolov5配置错误记录

这里是直接没有找到数据集&#xff0c;说明是路径错误。经过设置yaml后&#xff0c; # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] path: ../autodl-tmp/datasets/neu # dataset root dir tr…...

全平台数据 (数据库) 管理工具 DataCap 1.10.0 发布

当前版本涉及几个主要更新。 DataCap 已发布 发布版本发布时间1.10.02023-05-30 General 修复服务启动默认连接 mongo修复了 sql 模板的 h2 db update_time 和 create_time改进 H2 元数据管理获取类型改进 mysql 元数据管理获取类型固定元数据管理数据页默认为 1重构数据渲染…...

使用Mybatis接口开发

文章目录 目录 前言 公司项目用到了mybatis开发接口,虽然很简单,但是mybatis不是特别熟悉,这里学习一下 一、Mybatis接口绑定的两种方式 1.接口绑定实现方式 就是在接口的方法上加上Select,updateInsertDelete等注解 select注解介绍: 简便,能快速去操作sql,它只需要在mapper…...

数据采集技术的实现原理有哪些?

数据采集技术是指通过各种手段和技术手段&#xff0c;从互联网、移动设备、传感器等各种数据源中获取数据&#xff0c;并将其存储、处理和分析&#xff0c;以便为业务决策和应用提供支持。本文将介绍数据采集技术的实现原理&#xff0c;包括数据采集的基本流程、数据采集技术的…...

2023年数学建模随机森林:基于多个决策树的集成学习方法

2023年9月数学建模国赛期间提供ABCDE题思路加Matlab代码,专栏链接(赛前一个月恢复源码199,欢迎大家订阅):http://t.csdn.cn/Um9Zd 目录 目录 1. 什么是随机森林? 2. 随机森林的优缺点 3. 随机森林的构建过程...

OpenAI发布最新研究让大模型数学推理直接达到SOTA

&#x1f989; AI新闻 &#x1f680; OpenAI发布最新研究&#xff1a;基于过程奖励的监督方法&#xff0c;让大模型数学推理直接达到SOTA 摘要&#xff1a;OpenAI最新研究基于GPT-4微调&#xff0c;采用过程监督和结果监督两种监督方法&#xff0c;奖励每个正确推理步骤的过程…...

快速检测 GlassFish 任意文件读取漏洞的 Python 脚本

部分数据来源:ChatGPT 引言 当下,互联网安全问题正愈发严重,黑客利用各种漏洞进行攻击的频率也在持续增加。在2015年10月,一位名为“路人甲”的安全研究员在乌云上公开了一个名为“应用服务器glassfish存在通用任意文件读取漏洞”的漏洞(编号:wooyun-2010-0144595),该…...

Docker镜像更新通知器DIUN

什么是 DIUN ? Docker Image Update Notifier 是一个用 Go 编写的 CLI 应用程序&#xff0c;可作为单个可执行文件和 Docker 映像交付&#xff0c;用于当 Docker 映像在 Docker registry中更新时接收通知。 和老苏之前介绍过的 watchtower 不同&#xff0c;DIUN 只是通知&…...

插件框架PF4J-从理论到实践

PF4J:Plugin Framework for Java 目录 是什么&#xff1f; 不是什么&#xff1f; 特点 组件 主要类 流程概述 spring-pf4j 思考 功能模块化 我对pf4j的封装和使用demo GitHub - chlInGithub/pf4jDemo: pf4j demo 是什么&#xff1f; 开源轻量级的插件框架。通过插件…...

怎么将pdf文件免费转为扫描件

推荐两个工具&#xff0c;也算是给自己记一下 1、手机&#xff1a;扫描全能王APP 太好使了&#xff0c;可以直接拍照并转换为扫描件 不开会员的话会出现水印&#xff0c;因为我都是自己用或者交作业就没开 支持读取相册&#xff0c;一次一张、多张都可以 如果不想要水印也…...

vue+nodejs校园二手物品交易市场网站_xa1i4

。为满足如今日益复杂的管理需求&#xff0c;各类管理系统程序也在不断改进。本课题所设计的校园二手交易市场&#xff0c;使用vue框架&#xff0c;Mysql数据库、nodejs语言进行开发&#xff0c;它的优点代码不能从浏览器查看&#xff0c;保密性非常好&#xff0c;比其他的管理…...

Barra模型因子的构建及应用系列六之Book-to-Price因子

一、摘要 在前期的Barra模型系列文章中&#xff0c;我们构建了Size因子、Beta因子、Momentum因子、Residual Volatility因子和NonLinear Size因子&#xff0c;并分别创建了对应的单因子策略&#xff0c;其中Size因子和NonLinear Siz因子具有很强的收益能力。本节文章将在该系列…...

【c语言习题】使用链表解决约瑟夫问题

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c语言系列专栏&#xff1a;c语言之路重点知识整合 &#x…...

JVM之类的初始化与类加载机制

类的初始化 clinit 初始化阶段就是执行类构造器方法clinit的过程。此方法不需定义&#xff0c;是javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来。构造器方法中指令按语句在源文件中出现的顺序执行。clinit不同于类的构造器。(关联&#xff1a;…...

面试专题:java 多线程(1)----synchronized关键字相关问答

在java 多线程 面试中最多问题1.悲观锁和乐观锁&#xff1b;2.synchronized和lock的区别&#xff1b;3.可重入锁和非可重入锁的区别&#xff1b;4.多线程是解决什么问题的&#xff1b;5.线程池解决什么问题的&#xff1b;6.线程池原理&#xff1b;7.线程池使用注意事项&#xf…...

VMware SD-WAN 5.2 发布 - 软件定义的 WAN

VMware SD-WAN 5.2 发布 - 软件定义的 WAN SD-WAN 解决方案的领导者 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-sd-wan-5/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org 产品概述 软件定义的 WAN (SD-WAN)…...

Oracle+11g+RAC+PSU_EAM(2)

2.15 解压安装介质 在获取开篇1.2节中提到的安装介质如下&#xff1a; [rootebsrac1 ~]# ls -l -rw-r–r– 1 root root 1358454646 Apr 20 16:22 p13390677_112040_Linux-x86-64_1of7.zip -rw-r–r– 1 root root 1142195302 Apr 20 16:29 p13390677_112040_Linux-x86-64_…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...