opencv-26 图像几何变换04- 重映射-函数 cv2.remap()
什么是重映射?
重映射(Remapping)是图像处理中的一种操作,用于将图像中的像素从一个位置映射到另一个位置。重映射可以实现图像的平移、旋转、缩放和透视变换等效果。它是一种基于像素级的图像变换技术,可以通过定义映射关系来改变图像的几何形状和外观。
在重映射中,我们需要定义一个映射表(Map),这个映射表指定了源图像中每个像素点在目标图像中的位置。对于每个像素点 (x, y),映射表告诉我们在目标图像中的新位置 (x’, y’)。通过对所有像素点进行映射,我们就可以得到经过重映射变换后的新图像。
在OpenCV中,可以使用 cv2.remap() 函数来执行重映射操作。cv2.remap() 接受输入图像和一个表示映射关系的两个浮点型数组(map_x 和 map_y)。数组 map_x 和 map_y 的大小必须与输入图像的大小相同,并且每个元素 (x, y) 表示源图像中的像素点 (x, y) 在目标图像中的新位置 (x’, y’)。
重映射应用场景?
重映射在图像处理和计算机视觉领域有许多应用场景。以下是一些常见的重映射应用场景:
图像畸变校正:相机镜头引起的畸变(如透视畸变、鱼眼畸变等)会导致图像中的直线弯曲或形状失真。通过重映射技术,可以校正这些畸变,使图像看起来更加自然和真实。
图像配准:在多幅图像中找到对应点,并将它们对齐,使得它们在相同视角或坐标系下表现一致。这在图像拼接、全景图像合成和多视角图像处理中非常有用。
图像稳定:在视频处理中,当相机存在抖动或运动时,可以使用重映射技术来稳定视频,保持图像内容相对稳定,减少抖动效应。
视角变换:通过重映射,可以改变图像的视角,实现缩放、旋转、平移和透视等效果,从而得到不同角度或大小的图像。
增强现实 (AR) 应用:在AR应用中,通过对现实世界图像进行重映射,将虚拟物体或信息叠加到真实世界中,实现真实与虚拟的交互效果。
图像处理与滤波:重映射技术可以应用于图像处理中的滤波、图像增强和特效处理,从而实现各种图像变换和处理效果。
视频流处理:在实时视频流处理中,可以使用重映射技术对图像进行实时变换和校正,以满足特定的需求。
这些只是重映射在图像处理和计算机视觉中的一些常见应用场景。实际上,重映射技术非常灵活和强大,可以在许多不同的领域中发挥重要作用,帮助我们处理和改善图像数据。
映射参数的理解
OpenCV 内的重映射函数 cv2.remap()提供了更方便、更自由的映射方式,其语法格式如下:
dst = cv2.remap( src, map1, map2, interpolation[, borderMode[, borderValue]] )
式中:
dst 代表目标图像,它和 src 具有相同的大小和类型。
src 代表原始图像。
map1 参数有两种可能的值:
表示(x,y)点的一个映射。
表示 CV_16SC2 , CV_32FC1, CV_32FC2 类型(x,y)点的 x 值。
map2 参数同样有两种可能的值:
当 map1 表示(x,y)时,该值为空。
当 map1 表示(x,y)点的 x 值时,该值是 CV_16UC1, CV_32FC1 类型(x,y)点的 y 值。
Interpolation 代表插值方式
borderMode 代表边界模式。当该值为 BORDER_TRANSPARENT 时,表示目标图像内
的对应源图像内奇异点(outliers)的像素不会被修改。
borderValue 代表边界值,该值默认为 0。
重映射通过修改像素点的位置得到一幅新图像。在构建新图像时,需要确定新图像中每个像素点在原始图像中的位置。因此,映射函数的作用是查找新图像像素在原始图像内的位置。该过程是将新图像像素映射到原始图像的过程,因此被称为反向映射。在函数 cv2.remap()中,参数 map1 和参数 map2 用来说明反向映射,map1 针对的是坐标 x,map2 针对的是坐标 y。
需要说明的是,map1 和 map2 的值都是浮点数。因此,目标图像可以映射回一个非整数的值,这意味着目标图像可以“反向映射”到原始图像中两个像素点之间的位置(当然,该位置是不存在像素值的)。这时,可以采用不同的方法实现插值,函数中的 interpolation 参数可以控制插值方式。正是由于参数 map1 和参数 map2 的值是浮点数,所以通过函数 cv2.remamp()所能实现的映射关系变得更加随意,可以通过自定义映射参数实现不同形式的映射。
需要注意的是,函数 cv2.remap()中参数 map1 指代的是像素点所在位置的列号,
参数 map2 指代的是像素点所在位置的行号。例如,我们想将目标图像(映射结果图像)中某个点 A 映射
为原始图像内处于第 0 行第 3 列上的像素点 B,那么需要将 A 点所对应的参数 map1 对应位置上的值设为 3,参数 map2 对应位置上的值设为 0。
所以,通常情况下,我们将 map1 写为 mapx,并且将 map2 写成 mapy,以方便理解。
同样,如果想将目标图像(映射结果图像)中所有像素点都映射为原始图像内处于第 0 行
第 3 列上的像素点 B,那么需要将参数 map1 内的值均设为 3,将参数 map2 内的值均设为 0。
实验:
使用 cv2.remap()完成数组映射,将目标数组内的所有像素点都映射为原始图像内第 0 行第 3 列上的像素点,以此来了解函数 cv2.remap()内参数 map1 和 map2 的使
用情况。
根据题目要求,可以确定:
用来指定列的参数 map1(mapx)内的值均为 3。
用来指定行的参数 map2(mapy)内的值均为 0。
import cv2
import numpy as np
img=np.random.randint(0,256,size=[4,5],dtype=np.uint8)
rows,cols=img.shape
mapx = np.ones(img.shape,np.float32)*3
mapy = np.ones(img.shape,np.float32)*0
rst=cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)
print("img=\n",img)
print("mapx=\n",mapx)
print("mapy=\n",mapy)
print("rst=\n",rst)
运行结果:
img=[[253 90 32 65 181][187 184 148 12 212][157 229 255 138 115][156 38 62 89 241]]
mapx=[[3. 3. 3. 3. 3.][3. 3. 3. 3. 3.][3. 3. 3. 3. 3.][3. 3. 3. 3. 3.]]
mapy=[[0. 0. 0. 0. 0.][0. 0. 0. 0. 0.][0. 0. 0. 0. 0.][0. 0. 0. 0. 0.]]
rst=[[65 65 65 65 65][65 65 65 65 65][65 65 65 65 65][65 65 65 65 65]]
通过观察上述结果可知,目标图像(数组)dst 内的所有值都来源于原始图像中第 0 行第 3
列上的像素值 65。
复制
为了更好地了解重映射函数 cv2.remap()的使用方法,本节介绍如何通过该函数实现图像的复制。在映射时,将参数进行如下处理:
将 map1 的值设定为对应位置上的 x 轴坐标值。
将 map2 的值设定为对应位置上的 y 轴坐标值。
通过上述处理后,可以让函数 cv2.remap()实现图像复制。下面通过一个例题来观察实现复
制时,如何设置函数 cv2.remap()内的 map1 和 map2 参数的值。
使用函数 cv2.remap()完成数组复制,了解函数 cv2.remap()内参数 map1和 map2 的使用情况。
这里为了方便理解,将参数 map1 定义为 mapx,将参数 map2 定义为 mapy。后续程序中都采用了这种定义方式,后面不再重复说明。
import cv2
import numpy as np
img=np.random.randint(0,256,size=[4,5],dtype=np.uint8)
rows,cols=img.shape
mapx = np.zeros(img.shape,np.float32)
mapy = np.zeros(img.shape,np.float32)
for i in range(rows):for j in range(cols):mapx.itemset((i,j),j)mapy.itemset((i,j),i)
rst=cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)
print("img=\n",img)
print("mapx=\n",mapx)
print("mapy=\n",mapy)
print("rst=\n",rst)
运行程序,出现如下结果:
img=[[151 137 24 88 216][ 8 112 205 130 44][ 78 106 1 134 85][190 55 135 56 64]]
mapx=[[0. 1. 2. 3. 4.][0. 1. 2. 3. 4.][0. 1. 2. 3. 4.][0. 1. 2. 3. 4.]]
mapy=[[0. 0. 0. 0. 0.][1. 1. 1. 1. 1.][2. 2. 2. 2. 2.][3. 3. 3. 3. 3.]]
rst=[[151 137 24 88 216][ 8 112 205 130 44][ 78 106 1 134 85][190 55 135 56 64]]
通过本例可以观察到,参数 mapx 和参数 mapy 分别设置了 x 轴方向的坐标和 y 轴方向的
坐标。函数 cv2.remap()利用参数 mapx、mapy 所组成的数组构造的映射关系实现了图像的复制。
例如,rst 中的像素点[3,4]在 src 内的 x、y 轴坐标如下:
x 轴坐标取决于 mapx 中 mapx[3,4]的值,为 4。
y 轴坐标取决于 mapy 中 mapy[3,4]的值,为 3。
这说明 rst[3,4]来源于原始图像 src 的第 4 列(x 轴方向,由 mapx[3,4]决定)、第 3 行(y
轴方向,由 mapy[3,4]决定),即 rst[3,4]=src[3,4]。原始对象 src[3,4]的值为 64,所以目标对象
rst[3,4]的值为 64。
像绕 x 轴的翻转
import cv2
import numpy as np
img=cv2.imread("lena.png")
rows,cols=img.shape[:2]
mapx = np.zeros(img.shape[:2],np.float32)
mapy = np.zeros(img.shape[:2],np.float32)
for i in range(rows):for j in range(cols):mapx.itemset((i,j),j)mapy.itemset((i,j),rows-1-i)
rst=cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)
cv2.imshow("original",img)
cv2.imshow("result",rst)
cv2.waitKey()
cv2.destroyAllWindows()
,左图是原始图像,右图是翻转结果图像
还有绕Y 翻转,绕X,Y 轴翻转,更多操作多动作试试
相关文章:

opencv-26 图像几何变换04- 重映射-函数 cv2.remap()
什么是重映射? 重映射(Remapping)是图像处理中的一种操作,用于将图像中的像素从一个位置映射到另一个位置。重映射可以实现图像的平移、旋转、缩放和透视变换等效果。它是一种基于像素级的图像变换技术,可以通过定义映…...

SkyWalking链路追踪中span全解
基本概念 在SkyWalking链路追踪中,Span(跨度)是Trace(追踪)的组成部分之一。Span代表一次调用或操作的单个组件,可以是一个方法调用、一个HTTP请求或者其他类型的操作。 每个Span都包含了一些关键的信息&am…...
【前端知识】React 基础巩固(三十一)——Redux的简介
React 基础巩固(三十一)——Redux 一、Redux是个纯函数 概念 纯函数(确定的输入一定产生确定的输出,函数在执行过程中不产生副作用): 在程序设计中,若一个函数符合以下条件,那么这个函数就被称为纯函数…...

拦截Bean使用之前各个时机的Spring组件
拦截Bean使用之前各个时机的Spring组件 之前使用过的BeanPostProcessor就是在Bean实例化之后,注入属性值之前的时机。 Spring Bean的生命周期本次演示的是在Bean实例化之前的时机,使用BeanFactoryPostProcessor进行验证,以及在加载Bean之前进…...

RT thread 之 Nand flash 读写过程分析
文章目录 前言:什么是Nand Flash?1、Nand Flash 读取步骤2、从主存读到Cache2.1 在标准spi接口下读取过程2.2 测试时序(SPI频率30MHz) 3.从Cache读取数据3.1在标准spi接口读取过程测试时序 前言:什么是Nand Flash&…...

独立站最全出单营销指南,新手卖家赶紧学起来吧!
这是一个需要投入大量时间和精力的挑战,但只有经过筛选在众多品牌和渠道中找到最适合自己的营销策略,才能成功。 新手商家经常会发现自己有很多可以改进的地方:品牌的颜色、字体以及其他一些细节。但真正走向成熟的商家会意识到,…...

Git移除commit过的大文件
前言:在提交推送本地更改至仓库时,误将大文件给提交了,导致push时报错文件过大,因此需要将已经commit的大文件移除后再push 若已知要删除的文件或文件夹路径,则可以从第4步开始 1.对仓库进行gc操作 $ git gc 2.查询…...

再见 Spring Boot 1.X ,Spring Boot 2.X 走向舞台中心
2019年8月6日,Spring 官方在其博客宣布,Spring Boot 1.x 停止维护,Spring Boot 1.x 生命周期正式结束。 其实早在2018年7月30号,Spring 官方就已经在博客进行过预告,Spring Boot 1.X 将维护到2019年8月1日。 1.5.x 将会…...

Jsonp劫持
JSONP 介绍 jsonp是一种协议,准确的说,他是json的一种使用模式,为了解决Json受同源策略限制的问题。 基本语法 JSONP的基本语法为:callback({“name”:”test”, “msg”:”success”}) 常见的例子包括函数调用(如…...

STM32CubeIDE(串口)
目录 一、轮询模式 1.1 配置USART2为异步模式 1.2 500ms发送一次消息 1.3 通信结果 1.4 串口控制LED 二、中断收发 2.1 开启中断 2.2 中断发送接收 2.2.1 中断发送只需要调用接口 2.2.2 中断接收 2.3 实验结果 三、DMA模式与收发不定长数据 3.1 DMA通道配置 3.2 DMA…...

Python编程很简单,四步菜鸟到高手(文末送书5本)
🤵♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞Ǵ…...

Labview串口通信MSComm实现串口收发
文章目录 前言一、什么是 MSComm二、MSComm 控件下载三、MSComm 控件的注册四、使用 MSComm 控件1、前面板放置控件2、MSComm 的常用属性3、MSComm 控件的事件 五、实现串口收发1、搭建虚拟串口2、发送测试3、接收测试4、后面板核心程序框图 六、程序自取 前言 本文介绍使用 A…...
字节跳动 EB 级 Iceberg 数据湖的机器学习应用与优化
深度学习的模型规模越来越庞大,其训练数据量级也成倍增长,这对海量训练数据的存储方案也提出了更高的要求:怎样更高性能地读取训练样本、不使数据读取成为模型训练的瓶颈,怎样更高效地支持特征工程、更便捷地增删和回填特征。本文…...

CentOS 安装Mysql8
1.检查是否已经安装mysql,停止mysql服务,删除mysql ps -ef | grep -i mysql systemctl stop mysqld rpm -e mysql 2.配置仓库 更新秘钥 rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022 安装mysql8的yum源 rpm -Uvh https://dev.mysql.…...

3-Linux实操
Linux实践操作 开关机、重启、用户登陆注销关机&重启用户登陆和注销 用户管理添加用户修改用户密码删除用户查询用户信息切换用户查看当前用户用户组的添加和删除用户和组相关文件 实用指令指定运行级别init 命令帮助指令文件目录类时间日期类搜索查找类🔍压缩和…...
Yarn 集群的架构和工作原理
Yarn 的基本设计思想是将 MapReduce V1 中的 JobTracker 拆分为两个独立的服务:ResourceManager 和 ApplicationMaster。 ResourceManager 负责整个系统的资源管理和分配,ApplicationMaster 负责单个应用程序的管理。 ResourceManager RM 是一个全局的资…...
PostgreSQL-视图-03-查询对象依赖关系视图-dba_dependencies
PostgreSQL查询对象依赖关系视图 -- PostgreSQL查询对象依赖关系视图drop view if exists tzq.dba_dependencies; create view tzq.dba_dependencies as with source_obj as (select sp.oid,sp.proname,unnest(string_to_array(regexp_replace(regexp_replace(lower(sp.prosrc…...

Vue style中的 scoped 属性
Vue 中存在 scoped 属性,HTML5中也存在一个 scoped 属性,而且,这两者都是针对 css 样式处理的属性,所以很多文章在 解释 Vue scoped 的时候,都会把两者混为一谈,直接进把 HTML5 scoped 的定义搬到 Vue scop…...

移动端适配rem
1.安装amfe-flexible和postcss-pxtorem, npm install amfe-flexible --save npm install postcss-pxtorem5.1.1 (这里我使用的postcss-pxtorem是5.1.1版本)或者在pageage.json中写入 "amfe-flexible": "^2.2.1","postcss-pxtorem": …...

Go语言开发小技巧易错点100例(八)
往期回顾: Go语言开发小技巧&易错点100例(一)Go语言开发小技巧&易错点100例(二)Go语言开发小技巧&易错点100例(三)Go语言开发小技巧&易错点100例(四)Go…...

利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...