【Affine / Perspective Transformation】

在这里插入图片描述

文章目录

  • 仿射变换介绍
  • 仿射变换 python 实现——cv2.warpAffine
  • 透视变换
  • 透视变换 python 实现——cv2.warpPerspective
  • 牛刀小试
  • 各类变换的区别与联系
    • 仿射变换和单应性矩阵
    • 透视变换和单应性矩阵

仿射变换介绍

仿射变换(Affine Transformation),又称仿射映射,是在几何学中描述的一个向量空间进行线性变换后,再附加一个平移变换,从而映射到另一个向量空间的过程。以下是对仿射变换的详细解释:

  1. 定义:
    仿射变换是一个向量空间到另一个向量空间的映射,该映射由一个非奇异的线性变换(通过一次函数进行)和一个平移变换组成。
    在有限维的情况下,每个仿射变换可以由一个矩阵A和一个向量b给出,形式为A和一个附加的列b。

  2. 数学表示:
    仿射变换对应于一个矩阵和一个向量的乘法,而仿射变换的复合对应于普通的矩阵乘法,但要加上一个特定的扩展矩阵。
    仿射变换在数学上可以通过齐次坐标矩阵表示,其中包含一个平移向量。

  3. 特性:
    仿射变换保持了二维图形的 “平直性”,即变换后直线仍然是直线。
    仿射变换也保持了“平行性”,即变换后平行线仍然是平行线,且直线上点的位置顺序不变。

  4. 应用:
    仿射变换在计算机图形学、计算机视觉和图像处理等领域有着广泛的应用,如图像配准、图像纠正、纹理纠正以及创建全景图像等。

  5. 组成:
    仿射变换可以包含多种几何变换的组合,如平移、旋转、缩放(dilation)和剪切(shear)等。

  6. 实现:
    在图像处理中,如OpenCV这样的库提供了仿射变换的实现函数,如cv2.warpAffine(),它通过一个变换矩阵(映射矩阵)M来实现图像的仿射变换。

  7. 几何意义:
    仿射变换可以理解为一系列的原子变换(如平移、旋转、尺度变换等)的复合实现。

总结来说,仿射变换是一种强大的几何变换工具,它能够在保持图形基本形状特性的同时,实现图像的多种变换操作。

在这里插入图片描述

仿射变换 python 实现——cv2.warpAffine

OpenCV 库中 cv2.warpAffine 用于对图像进行仿射变换。以下是 cv2.warpAffine 函数的中文文档,详细解释了其参数、用法和原理。

一、函数原型

cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])

二、参数说明

  • src:
    类型:InputArray
    说明:输入图像,即待变换的图像。

  • M:
    类型:InputArray
    说明:2x3的变换矩阵,它定义了仿射变换的类型。通常,这个矩阵由cv2.getAffineTransform或cv2.getRotationMatrix2D等函数计算得到。
    矩阵形式:
    [a, b, c]
    [d, e, f]
    其中,a和e控制缩放,b和d控制旋转和剪切,c和f控制平移。

  • dsize:
    类型:Size
    说明:输出图像的大小,即变换后图像的尺寸。

  • dst:
    类型:OutputArray
    说明:输出图像,可选参数。如果提供,函数将把结果写入这个图像;否则,将创建一个新的图像。

  • flags:
    类型:int
    说明:插值方法的标识符。默认为cv2.INTER_LINEAR(双线性插值)。其他可用的选项包括cv2.INTER_NEAREST(最近邻插值)、cv2.INTER_AREA(区域插值)、cv2.INTER_CUBIC(双三次插值)等。

  • borderMode:
    类型:int
    说明:边界填充方式。默认为cv2.BORDER_CONSTANT(常量填充)。其他可用的选项包括cv2.BORDER_REPLICATE(复制填充)、cv2.BORDER_REFLECT(反射填充)等。

  • borderValue:
    类型:Scalar
    说明:如果边界模式为cv2.BORDER_CONSTANT,这个值表示用于填充的边界颜色值。默认为0(黑色)。

三、函数作用

cv2.warpAffine 函数通过对输入图像 src 应用一个仿射变换矩阵 M,生成一个输出图像 dst。仿射变换可以包括旋转、缩放、平移、倾斜等操作,是计算机视觉中常用的图像变换方法。

四、注意事项

变换矩阵 M 必须是一个2x3的矩阵,且矩阵中的值会影响变换的效果。

输出图像 dst 的大小 dsize 可以是任意大小,但通常建议与输入图像 src 的大小相近或相同,以避免不必要的图像失真。

插值方法 flags 的选择会影响变换后图像的质量,需要根据具体需求选择合适的插值方法。

边界填充方式 borderMode 和填充值 borderValue 主要用于处理变换后图像边界的像素值,需要根据实际情况设置。

透视变换

透视变换(Perspective Transformation)是一种二维坐标到三维坐标再到另一个二维坐标的映射,它利用透射中心、像点、目标点三点共线的条件,将图片投影到一个新的视平面,同时保持承影面上投影几何图形的不变性。以下是透视变换的详细介绍:

一、变换原理

二维到三维再到二维:透视变换首先将二维图像坐标转换到三维空间,然后再从三维空间映射到另一个二维平面。

保持几何图形不变:尽管图像经历了从二维到三维再到二维的转换,但透视变换能够确保承影面上的投影几何图形保持不变。

二、变换矩阵

透视变换的通用公式中涉及一个变换矩阵,通常是一个3x3的矩阵。这个矩阵可以分解为三个部分:

T1:对图像进行线性变换(如缩放、旋转)。
T2:对图像进行平移。
T3:通常设为1,表示对图像进行投射变换。

在这里插入图片描述

三、应用场景

透视变换在多个领域都有广泛的应用,包括但不限于:

文档扫描与校正:通过逆透视变换,可以校正扫描文档中的透视畸变,使其恢复到正常的平面状态。

视频监控与图像识别:在视频监控中,摄像机的视角和位置可能导致图像的透视变换。透视变换可以校正这种变换,以准确还原目标物体的形状和位置。在图像识别中,透视变换可用于图像配准,即将多幅图像进行对齐。

虚拟现实与增强现实:透视变换可以用于将虚拟场景与真实场景进行融合,或者将虚拟内容叠加到真实场景中,提供沉浸式体验。

平面投影与立体重建:在平面投影中,透视变换可以将三维场景的立体图像投影到二维平面上。在立体重建中,它可以通过对多幅图像进行透视校正,恢复出三维场景的真实形状和位置。

图像拼接与全景摄影:透视变换在图像拼接中用于将多幅图像进行对齐和融合,以创建全景图像。

四、与仿射变换的区别

透视变换是仿射变换的延续,仿射变换是透视变换的一种特殊形式。仿射变换保持了二维图形的“平直性”和“平行性”,即直线变换之后依然是直线,平行线依然是平行线。而透视变换提供了更大的灵活性,可以将一个四边形区域映射到另一个四边形区域

在这里插入图片描述

五、 总结

透视变换是一种强大的图像变换工具,它通过将图像投影到新的视平面来保持几何图形的不变性。它在多个领域都有广泛的应用,特别是在需要校正图像中的透视畸变或进行图像配准的场景中。

透视变换 python 实现——cv2.warpPerspective

cv2.warpPerspective 是 OpenCV 库中的一个函数,用于实现图像的透视变换。透视变换能够将一个图像映射到一个新的视平面上,并且保持图像的直线性和平行性。下面是对 cv2.warpPerspective 函数的中文文档,清晰分点表示并归纳相关信息:

一、函数原型

cv2.warpPerspective(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])

二、参数

  • src
    类型:InputArray
    说明:输入图像,即待进行透视变换的原始图像。

  • M
    类型:InputArray
    说明:3x3 的变换矩阵。这个矩阵通常由 cv2.getPerspectiveTransform 函数计算得到,描述了从原始图像到目标图像的映射关系。

  • dsize
    类型:Size 或 (int, int) 元组
    说明:输出图像的尺寸,以 (width, height) 的形式给出。

  • dst (可选)
    类型:OutputArray
    说明:输出图像,即透视变换后的图像。如果提供,函数将结果写入这个图像;否则,将创建一个新的图像。

  • flags (可选)
    类型:int
    说明:插值方法的标识符。它决定了如何计算输入图像和输出图像之间的像素值关系。常用的插值方法包括:
    cv2.INTER_LINEAR:双线性插值(默认)
    cv2.INTER_NEAREST:最近邻插值
    cv2.INTER_AREA:使用像素区域关系进行重采样
    cv2.INTER_CUBIC:双三次插值

  • borderMode (可选)
    类型:int
    说明:边界像素的插值方法。如果目标图像中的像素在原始图像之外,则根据此参数指定如何填充这些像素。常见的边界模式包括:
    cv2.BORDER_CONSTANT:使用常数值填充边界
    cv2.BORDER_REPLICATE:复制边界像素
    cv2.BORDER_REFLECT:反射边界像素

  • borderValue (可选)
    类型:Scalar
    说明:如果边界模式为 cv2.BORDER_CONSTANT,则指定用于填充边界的常数颜色值。默认为黑色(0)。

三、函数作用

cv2.warpPerspective 函数将输入图像 src 根据给定的透视变换矩阵 M 进行透视变换,并将结果保存到输出图像 dst 中。该函数在图像校正、图像拼接、目标跟踪等计算机视觉任务中广泛应用。

使用示例

python
import cv2  
import numpy as np  # 读取图像  
img = cv2.imread('input.jpg')  # 定义源图像和目标图像上的四个点  
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])  
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])  # 计算透视变换矩阵  
M = cv2.getPerspectiveTransform(pts1,pts2)  # 设置输出图像大小  
dsize = (300, 300)  # 进行透视变换  
dst = cv2.warpPerspective(img, M, dsize)  # 显示图像  
cv2.imshow('Input', img)  
cv2.imshow('Output', dst)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

四、注意事项

变换矩阵 M 必须是一个 3x3 的矩阵,通常由 cv2.getPerspectiveTransform 计算得到。

插值方法 flags 和边界模式 borderMode 的选择会影响变换后图像的质量和边界像素的填充方式,应根据实际需求进行选择。

如果 dst 不为空,则 cv2.warpPerspective 会将结果写入 dst;否则,会创建一个新的图像。

透视变换通常用于校正图像的透视畸变,或者将一个物体从不同的视角投影到一个平面上。

牛刀小试

参考学习来自 【opencv实践】仿射变换和透视变换

import cv2
import numpy as npsrcImage = cv2.imread("./1.png")road_w = 540
road_h = 850imgPts = np.float32([[58, 462],[1007, 462],[440, 299],[639, 299],])objPts = np.float32([[50, 780],[490, 780],[50, 150],[490, 150]])M = cv2.getPerspectiveTransform(imgPts, objPts)
print(M)dstImage = cv2.warpPerspective(srcImage, M, (road_w, road_h))"draw points"
for i in range(4):cv2.circle(srcImage, center=(int(imgPts[i][0]), int(imgPts[i][1])), radius=5, color=[0, 0, 255], thickness=-1)cv2.circle(dstImage, center=(int(objPts[i][0]), int(objPts[i][1])), radius=5, color=[255, 0, 0], thickness=-1)"draw line"
for i in range(0, 4, 2):cv2.line(srcImage, pt1=(int(imgPts[i][0]), int(imgPts[i][1])), pt2=(int(imgPts[i+1][0]), int(imgPts[i+1][1])),color=[0, 0, 255], thickness=5, lineType=cv2.LINE_AA)cv2.line(dstImage, pt1=(int(objPts[i][0]), int(objPts[i][1])), pt2=(int(objPts[i+1][0]), int(objPts[i+1][1])),color=[255, 0, 0], thickness=5, lineType=cv2.LINE_AA)"show"
cv2.imshow("source", srcImage)
cv2.imshow("perspective", dstImage)
# cv2.imwrite("source.jpg", srcImage)
# cv2.imwrite("perspective.jpg", dstImage)
cv2.waitKey(0)
cv2.destroyAllWindows()

输入图像

在这里插入图片描述

选取四个点

[58, 462],
[1007, 462],
[440, 299],
[639, 299],

在这里插入图片描述
设定四个点仿射变换后的坐标

[50, 780],
[490, 780],
[50, 150],
[490, 150]

获取透视变换矩阵

[[-3.73905835e-01 -1.07177303e+00  4.76523333e+02][-2.25793124e-16 -3.70345076e+00  1.08196566e+03][-0.00000000e+00 -3.91005823e-03  1.00000000e+00]]

透视变换

在这里插入图片描述

各类变换的区别与联系

在这里插入图片描述

在这里插入图片描述

仿射变换和单应性矩阵

我就看看看看的回答

在这里插入图片描述

gamemonkey的回答

在这里插入图片描述

透视变换和单应性矩阵

来自 基础矩阵、本质矩阵、单应性矩阵、透视变换、仿射变换

单应性矩阵:在两视几何中,可以这样理解,两架相机拍同一空间上得到两幅图像AB,其中一幅A在另一幅B存在一种变换而且是一一对应的关系,他们之间可以用矩阵表示 这个矩阵用单应矩阵

在这里插入图片描述

仿射变换affine是透视变换的子集,透视变换是通过homography单应矩阵实现的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/347008.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

适配器模式和装饰器模式

文章目录 适配器模式1.引出适配器模式1.多功能转换插头2.基本介绍3.工作原理 2.类适配器1.基本介绍2.类图3.代码实现1.Voltage220V.java2.Voltage5V.java3.VoltageAdapter.java4.Phone.java5.Client.java6.结果 4.类适配器的注意事项 3.对象适配器1.基本介绍2.使用对象适配器改…

C51单片机 串口打印printf重定向

uart.c文件 #include "uart.h"void UartInit(void) //4800bps11.0592MHz {PCON | 0x80; //使能波特率倍速位SMODSCON 0x50; //8位数据,可变波特率。使能接收TMOD & 0x0F; //清除定时器1模式位TMOD | 0x20; //设定定时器1为8位自动重装方式TL1 0xF4; //设…

明天15点!如何打好重保预防针:迎战HVV经验分享

在当今数字化时代,网络攻击日益猖獗,各行各业面临的网络安全威胁不断升级。从钓鱼邮件到复杂的APT攻击,网络犯罪分子的手法层出不穷,给各行各业的信息安全带来了前所未有的挑战。 在这样的背景下,"HVV行动"应…

那些年我看过的技术书(持续更新,大佬的成长之路)

作为一个技术人啊,要学会多看书,发展自己。哦也!你可以不关注,就把文章点个收藏吧,万一以后想看书了呢? 网络安全 CTF篇 入门篇 《极限黑客攻防:CTF赛题揭秘》 Web篇 Reserve篇 《IDApro…

ON DUPLICATE KEY UPDATE 子句

ON DUPLICATE KEY UPDATE 是 MySQL 中的一个 SQL 语句中的子句,主要用于在执行 INSERT 操作时处理可能出现的重复键值冲突。当尝试插入的记录导致唯一索引或主键约束冲突时(即试图插入的记录的键值已经存在于表中),此子句会触发一…

virtual box安装invalid installation directory

问题原因 看官方文档Chapter 2. Installation Details 第2.1.2所示,安装目录需要满足两个条件: 一是:需要安装目录的所有父目录都要满足以下访问控制条件 Users S-1-5-32-545:(OI)(CI)(RX) Users S-1-5-32-545…

【Python列表解锁】:掌握序列精髓,驾驭动态数据集合

文章目录 🚀一、列表🌈二、常规操作💥增💥删💥改💥查 ⭐三、补充操作 🚀一、列表 列表是一个能够存储多个同一或不同元素的序列 列表:list ---- [] 列表属于序列类型(容器…

ES升级--05--快照生成 和备份

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 备份ES数据1.关闭集群自动均衡2.执行同步刷新3.停止集群节点的Elasticsearch服务4.修改Elasticsearch配置文件,开启快照功能,配置仓库目录为…

axure9设置组件自适应浏览器大小

问题:预览时不展示下方的滚动条 方法一:转化为动态面板 1.在页面上创建一个矩形 2.右键-转化为动态面板 3.双击进入动态面板设置 4.设置动态面板矩形的颜色 5.删除原来的矩形 6.关闭动态面板,点击预览 7.此时可以发现底部没有滚动条了 方法…

Java进阶_多态特性

生活中的多态 多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作,如图所示: 现实中,比如我们按下 F1 键这个动作,同一个事件发生在不同的对象上会产生不同的结果。…

ElasticSearch学习笔记之三:Logstash数据分析

第3章 Logstash数据分析 Logstash使用管道方式进行日志的搜集处理和输出。有点类似*NIX系统的管道命令 xxx | ccc | ddd,xxx执行完了会执行ccc,然后执行ddd。 在logstash中,包括了三个阶段: 输入input --> 处理filter(不是必须…

Android 代码打印meminfo

旨在替代adb shell dumpsys meminfo packageName,在log打印meminfo,以便分析内存情况 ActivityManager.MemoryInfo memoryInfo new ActivityManager.MemoryInfo(); activityManager.getMemoryInfo(memoryInfo); long totalMemory Runtime.getRuntime(…

6、后端项目初始化

打开idea后, New Project ,用Maven构建 Spring Boot 项目 点击Next后:先勾选两个基本的依赖,后面再手动添加其它需要的依赖 Spring Web: 表示是一个web应用程序 Lombok:写实体类的时候添加Data注解后就会自动加上g…

Node.js环境搭建

背景 想接触下node开发, 打算做个node环境 一、安装包获取 我喜欢使用压缩包解压然后配置的方式进行 地址为: Index of /download/release/ ,可按需选择自己的版本,我选择了如下版本 二、解压配置 将压缩包解压只自己想要安装的文件加下,配置环境变量,解压如下所示: …

贪 吃 蛇

简介 简易贪吃蛇,使用 javax.swing 组件构建游戏界面,通过监听键盘按键实现游戏操纵。 功能设计 按1 - 开始游戏按2 - 重新开始按3 - 暂停/继续按Esc-退出游戏统计吃到的苹果个数(得分)难度控制,得分超过阈值时难度…

第十五届蓝桥杯pb组国赛E题[马与象] (15分)BFS算法 详解

博客主页:誓则盟约 系列专栏:IT竞赛 专栏 关注博主,后期持续更新系列文章 如果有错误感谢请大家批评指出,及时修改 感谢大家点赞👍收藏⭐评论✍ 问题描述: 小蓝有一个大小为 N N 的棋盘(棋…

暂停系统更新

电脑左下角搜索注册表编辑器 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings 找到这个目录 打开FlightSettingsMaxPauseDays,没找到的话就创建一个同名文件夹然后选择10进制填入3550​​​​​​​ 最后进入系统暂停更新界面选择最下面…

Javaweb03-Servlet技术1(Servlet,ServletConfig,ServletContext)

Servlet技术(Servlet,ServletConfig,ServletContext) 1.Servlet的概述 Servlet是运行在Web服务器端的Java应用程序,它使用Java语言编写。与Java程序的区别是,Servlet 对象主要封装了对HTTP请求的处理,并且它的运行需要Servlet容器(Tomcat)的…

网工使用频率最高的6款软件,都有的绝对是资深打工人

号主:老杨丨11年资深网络工程师,更多网工提升干货,请关注公众号:网络工程师俱乐部 晚上好,我的网工朋友。 有不少朋友问到,深耕网络工程师需要哪些软件? 其实网工行业需要的软件还挺多的&…

Linux操作系统学习:day02

内容来自:Linux介绍 视频推荐:[Linux基础入门教程-linux命令-vim-gcc/g -动态库/静态库 -makefile-gdb调试]( day02 5、Linux目录结构 操作系统文件结构的开始,只有一个单独的顶级目录结构,叫做根目录。所有一切都从“根”开始…