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…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...

c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...