OpenCV开发笔记(七十五):相机标定矫正中使用remap重映射进行畸变矫正
若该文为原创文章,转载请注明原文出处
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/136293833
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)
OpenCV开发专栏(点击传送门)
上一篇:《OpenCV开发笔记(七十四):OpenCV3.4.1+ffmpeg3.4.8交叉编译移植到海思平台Hi35xx平台》
下一篇:持续补充中…
前言
相机标定,重映射可以进行插值映射从而矫正图像,这是一种方法,也有矩阵映射方法,本篇使用重映射方式解说畸变矫正的计算原理。
Demo
横向纵向区域固定拉伸:

横向纵向拉伸:

右下角拉伸:

相机畸变矫正
标定相机需要做两件事:
- 纠正畸变的影响
- 根据图像重构三位场景
纠正畸变的影响
Opencv提供了可以直接使用的矫正算法,即通过输入原始图像和由函数cv::calibrateCamera()得到的畸变系数,生成校正后的图像。(注意:这里可使用用cv::undistort()使用该算法直接完成所需任务,也可以使用函数cv::iniitUndistorRectifyMap()和cv::remap()来更有效的处理。
矫正映射remap(畸变映射)
当进行图像矫正时,必须指定输入图像的每个像素在输出图像中移动到的位置,成为“矫正映射”(畸变映射)。
双通道浮点数表示方式
N x M的矩阵A中,重映射由双通道浮点数的N x M的矩阵B表示,对于图像A中的任意一点aPoint(i, j),映射为b1Point(i’, j’)和b2Point(i’, j’),在A中假设i=2,j=3,那么(假设重映射之后4.5,5.5)在B1中b1Point(i’, j’)值为4.5,b2Point(i’, j’)值为5.5,由于坐标是浮点数,那么需要插值得到整数位置以及中间过渡的区域颜色(平滑处理)。

双矩阵浮点数表示方式
双矩阵浮点数表示,N x M的矩阵A中,重映射由一对N x M的矩阵B和C描述,这里所有的N x M矩阵都是单通道浮点矩阵,在A中的点aPoint(i, j),重映射矩阵B中的点bPoint(i,j)存储了重映射后的i’ (映射后的i坐标), 重映射矩阵C中的点cPoint(i,j)存储了重映射后的j’(映射后的j坐标)。

定点表示方式
映射由双通道有符号整数矩阵(即CV_16SC2类型)表示。该方式与双通道浮点数表示方式相同,但使用此格式要快得多(笔者理解:由浮点数插值改为整数插值,会要快一些,但是肯定双通道浮点数的表示方式图像效果会稍微好一些)。

remap核心关键
在于得到插值的坐标系来映射新位置的x和y位置,要渐近等,所以本方法的核心关键在于得到标定后的矩阵,得到映射矩阵的方式可以自己写算法,也可以使用其他方式,后续文章继续深入这块。
函数原型
void remap( InputArray src,OutputArray dst,InputArray map1,InputArray map2,int interpolation,int borderMode = BORDER_CONSTANT,const Scalar& borderValue = Scalar());
- 参数一:InputArray类型的src,一般为cv::Mat;
- 参数二:OutputArray类型的dst,目标图像。它的大小与map1相同,类型与src相同。
- 参数三:InputArray类型的map1,它有两种可能的表示对象:表示点(x,y)的第一个映射或者表示CV_16SC2 , CV_32FC1 或CV_32FC2类型的x值。
- 参数四:InputArray类型的map2,它也有两种可能的表示对象,而且他是根据map1来确定表示哪种对象。若map1表示点(x,y)时,这个参数不代表任何值,否则,表示CV_16UC1 , rCV_32FC1类型的y值(第二个值)。
- 参数五:int类型的interpolation,使用的插值方法;
- 参数六:int类型的borderMode,边界处理方式;
- 参数七:Scalar类型的borderValue,重映射后,离群点的背景,需要broderMode设置为BORDER_CONSTRANT时才有效。(离群点:当图片大小为400x300,那么对应的map1和map2范围为0399、0299,小于0或者大于299的则为离散点,使用该颜色填充);
Demo源码
void OpenCVManager::testRemap2()
{std::string srcFilePath = "D:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/25.jpg";// 步骤一:读取文件cv::Mat srcMat = cv::imread(srcFilePath);// 缩放一下int width = 400;int height = 400;cv::resize(srcMat, srcMat, cv::Size(width, height));// 步骤二:映射矩阵cv::Mat mapX;cv::Mat mapY;mapX.create(srcMat.size(), CV_32FC1);mapY.create(srcMat.size(), CV_32FC1);// 算法:这里400x400,将0~100放大至0~200,将100~400映射为200~400// 算法:这里400x400,将0~100放大至0~200,将100~400映射为200~400
#if 0for(int row = 0; row < srcMat.rows; row++){for(int col = 0; col < srcMat.cols; col++){
// if(true)if(col < 200){mapX.at<float>(row, col) = static_cast<float>(col * 1.0f / 2);}else{mapX.at<float>(row, col) = static_cast<float>(100 + (col - 200) * 1.0f / 2 * 3);}
// if(true)if(row < 200){mapY.at<float>(row, col) = static_cast<float>(row * 1.0f / 2);}else{mapY.at<float>(row, col) = static_cast<float>(100 + (row - 200) * 1.0f / 2 * 3);}}}
#endif
#if 0for(int row = 0; row < srcMat.rows; row++){for(int col = 0; col < srcMat.cols; col++){// 这里是 0~200 缩放为 0~100 缩小 // 比例系数if(col == 0){mapX.at<float>(row, col) = static_cast<float>(col);}else if(col < 200){mapX.at<float>(row, col) = static_cast<float>(col * 1.0f / 2 * (col * 1.0f / 199));}else{mapX.at<float>(row, col) = static_cast<float>(col * 1.0f / 2 * (col * 1.0f / 199));}if(row == 0){mapY.at<float>(row, col) = static_cast<float>(row);}else if(row < 200){mapY.at<float>(row, col) = static_cast<float>(row * 1.0f / 2 * (row * 1.0f / 199));}else{mapY.at<float>(row, col) = static_cast<float>(row * 1.0f / 2 * (row * 1.0f / 199));}}}
#endif
#if 1for(int row = 0; row < srcMat.rows; row++){for(int col = 0; col < srcMat.cols; col++){// 比例系数 0~1.0(400~800)/400mapX.at<float>(row, col) = static_cast<float>(col * ((col + 1 + 400) * 1.0f / 800));mapY.at<float>(row, col) = static_cast<float>(row * ((row + 1 + 400) * 1.0f / 800));}}
#endifcv::Mat dstMat;cv::remap(srcMat,dstMat,mapX,mapY,CV_INTER_LINEAR,cv::BORDER_CONSTANT,cv::Scalar(255, 0, 0));cv::imshow("1", srcMat);cv::imshow(_windowTitle.toStdString(), dstMat);cv::waitKey(0);
}
对应工程模板v1.66.0

上一篇:《OpenCV开发笔记(七十四):OpenCV3.4.1+ffmpeg3.4.8交叉编译移植到海思平台Hi35xx平台》
下一篇:持续补充中…
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/136293833
相关文章:
OpenCV开发笔记(七十五):相机标定矫正中使用remap重映射进行畸变矫正
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/136293833 各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究 红胖子(红模仿…...
光伏预测 | Matlab基于CNN-SE-Attention-ITCN的多特征变量光伏预测
光伏预测 | Matlab基于CNN-SE-Attention-ITCN的多特征变量光伏预测 目录 光伏预测 | Matlab基于CNN-SE-Attention-ITCN的多特征变量光伏预测预测效果基本描述模型简介程序设计参考资料 预测效果 基本描述 Matlab基于CNN-SE-Attention-ITCN的多特征变量光伏预测 运行环境: Matla…...
k8s学习笔记-基础概念
(作者:陈玓玏) deployment特别的地方在于replica和selector,docker根据镜像起容器,pod控制容器,job、cronjob、deployment控制pod,job做离线任务,pod大多一次性的,cronj…...
C语言 变量
变量其实只不过是程序可操作的存储区的名称。C 中每个变量都有特定的类型,类型决定了变量存储的大小和布局,该范围内的值都可以存储在内存中,运算符可应用于变量上。 变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头…...
2024年2月16日优雅草蜻蜓API大数据服务中心v1.1.1大更新-UI全新大改版采用最新设计ui·增加心率计算器·退休储蓄计算·贷款还款计算器等数接口
2024年2月16日优雅草蜻蜓API大数据服务中心v1.1.1大更新-UI全新大改版采用最新设计ui增加心率计算器退休储蓄计算贷款还款计算器等数接口 更新日志 前言:本次更新中途跨越了很多个版本,其次本次ui大改版-同步实时发布教程《带9.7k预算的实战项目layuiph…...
WEB漏洞 逻辑越权之支付数据篡改安全
水平越权 概述:攻击者尝试访问与他拥有相同权限的用户的资源 测试方法:能否通过A用户操作影响到B用户 案例:pikachu-本地水平垂直越权演示-漏洞成因 1)可以看到kobe很多的敏感信息 2)burp抓包,更改user…...
45、WEB攻防——通用漏洞PHP反序列化POP链构造魔术方法原生类
文章目录 序列化:将java、php等代码中的对象转化为数组或字符串等格式。代表函数serialize(),将一个对象转换成一个字符;反序列化:将数组或字符串等格式还成对象。代表函数unserialize(),将字符串还原成一个对象。 P…...
雾锁王国服务器怎么建?雾锁王国服务器搭建方法
雾锁王国Enshrouded服务器搭建怎么搭建?非常简单,阿里云计算巢雾锁王国程序,可以一键搭建雾锁王国多人联机服务器,腾讯云是基于雾锁王国镜像系统,阿里云服务网aliyunfuwuqi.com汇总雾锁王国服务器搭建,超简…...
设计模式篇---观察者模式
文章目录 概念结构实例总结 概念 观察者模式:定义对象之间的一种一对多的依赖关系,使得每当一个对象状态发生改变时,其他相关依赖对象都得到通知并被自动更新。 观察者模式是使用频率较高的一个模式,它建立了对象与对象之间的依赖…...
Docker常用命令Top20
Docker常用命令Top20 Docker是一种容器化平台,通过使用Docker,开发人员可以轻松地打包、交付和运行应用程序。以下是Docker中最常用的20个命令: docker run: 运行一个容器。 docker run <image_name>docker ps:…...
Redis的发布订阅机制及其使用场景
Redis的发布订阅(Pub/Sub)机制是一种消息通信模式,其中发送者(发布者)将消息发送到特定的频道,而订阅者则订阅其中一个或多个频道,以接收感兴趣的消息。这种模式可以用于构建实时通信系统、消息…...
计算机网络的基础知识
网络的性能指标:网络速率,bpsbit/s; 时延包括四个组成部分:发送时延、传播时延、排队时延、处理时延; 网络各个层次结构设计的基本三原则:各个层次之间是相互独立的,每一个层之间有足够的灵活…...
QT-Http post 同步请求
在 Qt 中,你可以使用 QNetworkAccessManager 对象的 sendCustomRequest 方法来发送同步的 HTTP 请求。以下是一个演示如何使用该方法发送同步 HTTP POST 请求的示例代码: #include <QCoreApplication> #include <QNetworkAccessManager> #i…...
【JVM】StringTable 字符串常量池
参考:javaGuide 字符串常量池 是 JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建 String的不可变性 1.通过字面量的方式(区别于new)给一个…...
Unity中URP实现水体(水的焦散)
文章目录 前言一、原理1、 通过深度图,得到 对应像素 在 世界空间下的Z值2、得到模型顶点在 观察空间 下的坐标3、由以上两点得到 深度图像素 对应的 xyz 值4、最后,转化到 模型本地空间下,用其对焦散纹理采样 二、实现1、获取深度图2、在顶点…...
vue构建版本
完整版:同时包含编译器和运行时的版本。 编译器:用来将模板字符串编译成为 JavaScript 渲染函数的代码。 运行时runtime:用来创建 Vue 实例、渲染并处理虚拟 DOM 等的代码。基本上就是除去编译器的其它一切。 UMD:UMD 版本可以…...
Docker挂载镜像到本地(日常记录)
Docker挂载镜像到本地 1、进入jar包文件夹 cd docker-publish/2、编写DockFile文件 #使用Jdk8环境作为基础镜像,如果镜像不在本地则会从DockerHub进行下载 #FROM openjdk:8-jdk-alpine FROM openjdk:11 #VOLUME 指定了临时文件目录为/tmp。其效果是在主机 /var/l…...
【Elasticsearch查询】精确查询
文章目录 复合查询constant_score querybool querydis_max queryfunction_score queryboosting query单层嵌套双层嵌套 词项查询term query(词项查询)数字的精确查询文本的精确查询查询优化 terms query(多词项查询)terms_set que…...
小狐狸chat2.7.2免授权修复版可用版
小狐狸chat2.7.2免授权修复版可用版 在网络上面找了好几个版本不能使用,今天发布这个仔细测试正常使用 主要功能:独立版无限多开支持分销会员充值自己APP打包小程序万能创作MJ绘图多个国内接口 国外很火的ChatGPT,这是一种基于人工智能技术…...
通过QScrollArea寻找最后一个弹簧并且设置弹簧大小
项目原因,最近需要通过QScrollArea寻找其中最后一个弹簧并且设置大小和策略,因为无法直接调用UI指针,所以只能用代码寻找。 直接上代码: if (m_scrollArea){int iScrollWidth m_labelSelectedTitle->width();m_scrollArea-&g…...
国民技术N32G455VE开发实战:JLink_V644g添加芯片全流程(附资源包)
国民技术N32G455VE开发实战:JLink_V644g环境下的芯片支持全流程解析 在嵌入式开发领域,快速搭建开发环境并实现芯片的调试支持是项目推进的关键第一步。对于采用国民技术N32G455VE这款高性能MCU的开发者来说,如何在JLink_V644g调试器中添加对…...
Android音频调试实战:用dumpsys media.audio_flinger揪出音频卡顿的元凶
Android音频调试实战:用dumpsys media.audio_flinger揪出音频卡顿的元凶 当你在开发一款音乐播放应用时,突然收到用户反馈说音频播放时有明显的卡顿和杂音。作为开发者,你可能会感到一头雾水——是应用层的问题?还是系统底层的问题…...
2025届最火的AI写作神器解析与推荐
Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 处于学术写作这个范畴里,恰当地运用论文AI工具可明显提高写作的效率跟质量。当前…...
自媒体增长引擎中内容量化成垂直领域知识库的思考
把高赞视频(尤其是剧情类)的内容量化成垂直领域知识库——这才是让agent真正“懂垂直领域”的核心护城河。 市面上很多AI工具只做“生成”,而如果把“爆款拆解→量化→知识库”做扎实,就能形成数据驱动的增长闭环,让选…...
实战指南:如何高效配置VcXsrv实现Windows与Linux图形应用无缝连接
实战指南:如何高效配置VcXsrv实现Windows与Linux图形应用无缝连接 【免费下载链接】vcxsrv VcXsrv Windows X Server (X2Go/Arctica Builds) 项目地址: https://gitcode.com/gh_mirrors/vc/vcxsrv 在跨平台开发工作中,开发者经常面临一个核心挑战…...
如何用Python轻松下载加密m3u8视频:解密、多线程、批量处理全攻略
如何用Python轻松下载加密m3u8视频:解密、多线程、批量处理全攻略 【免费下载链接】m3u8_downloader 项目地址: https://gitcode.com/gh_mirrors/m3/m3u8_downloader 你是否曾遇到过想保存在线课程、收藏精彩视频,却因为复杂的HLS流媒体加密技术…...
破局性能与灵活性的博弈:Kuikly 动态化方案的场景实战与评估
在移动互联网进入存量竞争的时代,App 的业务迭代速度与用户体验之间往往存在着天然的“鱼和熊成鱼”的矛盾。为了实现业务的快速上线,开发者尝试了从 H5 到 React Native,再到 Flutter 的各种跨端动态化方案。然而,在追求极致性能…...
基于图神经网络的智能合约漏洞检测
研一小白,我的课题就是基于图神经网络做合约漏洞检测,有无高手指教一下啊,不知道怎么办,所以来csdn上碰碰运气,看有没有做过类似课题的,关于数据集怎么找、怎么标记以及如何写小论文等...
(二)永磁同步电机矢量控制(三电平)——三电平SVPWM调制算法中的扇区与区域判断实战解析
1. 三电平SVPWM的核心挑战:扇区与区域判断 我第一次接触三电平SVPWM算法时,最头疼的就是这个扇区和区域判断。当时在实验室调试电机,明明按照教材上的步骤操作,可电机就是转不起来。后来才发现是区域判断的逻辑写反了。今天就和大…...
视觉模型在生产环境中失败的主要原因
计算机视觉现已成为大多数行业广泛采用的关键人工智能技术,其核心价值在于使机器能够解释和分析视觉数据,进而执行从医学成像、机器人技术到制造业自动化、零售智能化等各类实际任务。 然而,构建可靠的计算机视觉系统并非易事。这一过程通常需要开发视觉 AI 模型 —— 该…...
