【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 np

srcImage = cv2.imread("./1.png")

road_w = 540
road_h = 850

imgPts = 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单应矩阵实现的

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙轻内核A核源码分析系列四(2) 虚拟内存

本文我们来熟悉下OpenHarmony鸿蒙轻内核提供的虚拟内存(Virtual memory)管理模块。 本文中所涉及的源码,以OpenHarmony LiteOS-A内核为例,均可以在开源站点 https://gitee.com/openharmony/kernel_liteos_a 获取。如果涉及开发板…

基于微信小程序的“最多跑一次”警务信息管理系统

作者主页:Java码库 主营内容:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】:Java 【框架】:ssm 【…

Linux用户,用户组,所有者权限分配,sftp用户权限分配

注意以下命令执行需要在root用户下执行 tenant命令切换至root命令 sudo -do root 删除用户信息 1.不删除用户主目录 userdel user_name 2.删除用户主目录 userdel -r user_name usermod命令修改用户账户权限 更改用户名 sudo usermod -l newusername oldusername 更…

亚马逊竞品分析之如何查找竞品

初选之后,要对产品进行竞品分析,查找竞品的方法: 1.Best Seller榜单查找 进入到该类目的BS榜单去找跟你选中的产品的竞品 看完BS榜单会找出一部分竞品 这个找相似也可以点击,是插件的一个以图搜图的功能,不过有的时候不太好使,某些同款产品可能搜不到。 Edge浏览器搭…

The First项目报告:Stargate Finance重塑跨链金融的未来

Stargate Finance是一个基于LayerZero协议的去中心化金融平台,自2022年3月由LayerZero Labs创建以来,一直致力于为不同区块链之间的资产转移提供高效、低成本的解决方案。凭借其独特的跨链技术和丰富的DeFi服务,Stargate Finance已成为连接不…

Vue3相关语法内容,组件传值,事件监听,具名插槽。

1、Vue3相关语法内容 赋值语句(ref、reactive系列)组件传值(父子,子父)watch,watchEffect监听slot具名插槽 1、赋值语法(ref,reactive) 1.1、ref 、isRef、 shallowRef、triggerRef、customRef 支持所有的类型&…

视觉SLAM14精讲——相机与图像3.2

视觉SLAM14精讲 三维空间刚体运动1.0三维空间刚体运动1.1三维空间刚体运动1.2李群与李代数2.1相机与图像3.1 视觉SLAM14精讲——相机与图像3.2 视觉SLAM14精讲畸变有关重投影误差缩放实际使用 畸变 相机畸变是相机镜头光学缺陷所致的缺陷, 在光学领域这种问题是没…

【学习笔记】使用gcc编译程序并检查依赖的库

编译 gcc echo.c -o app -lfcgi-o app:指定编译后的输出文件名为 app。 -lfcgi:告诉编译器链接 FastCGI 库。 检查 ldd appldd 是一个在 Unix 和类 Unix 系统中用来打印一个已编译的程序所依赖的共享库列表的命令。当你运行 ldd app 命令时&#xff0…

机器人建模、运动学与动力学仿真分析(importrobot,loadrobot,smimport)

机器人建模、运动学与动力学仿真分析是机器人设计和开发过程中的关键步骤。 一、机器人建模 机器人建模是描述机器人物理结构和运动特性的过程。其中,URDF(Unified Robot Description Format)是一种常用的机器人模型描述方法。通过URDF&…

【CTS】android CTS测试

android CTS测试 1.硬件准备2. 软件准备3. 下载 CTS3.1 cts3.2 解压 CTS 包: 4 配置adb fastboot5 检查 Java 版本6 安装aapt26.1 下载并安装 Android SDK6.2 找到 aapt2 工具6.3 配置环境变量 7. 准备测试设备8. 运行 CTS 测试8.1 启动 CTS: 9. 查看测试…

vue-cli 快速入门

vue-cli (目前向Vite发展) 介绍:Vue-cli 是Vue官方提供一个脚手架,用于快速生成一个Vue的项目模板。 Vue-cli提供了如下功能: 统一的目录结构 本地调试 热部署 单元测试 集成打包上线 依赖环境:NodeJ…

第8章 函数

第8章 函数 8.1 定义函数8.1.1 向函数传递信息8.1.2 实参和形参 8.2 传递实参8.2.1 位置实参8.2.2 关键字实参8.2.3 默认值 8.3 返回值8.3.1 返回简单值8.3.2 让实参变成可选的8.3.3 返回字典8.3.4 结合使用函数和 while 循环 8.4 传递列表8.4.1 在函数中修改列表8.4.2 禁止函数…

DeepSpeed Mixture-of-Quantization (MoQ)

属于QAT (Quantization-Aware Training)的一种,训练阶段用量化。 特点是: 1. 从16-bit INT开始训练,逐渐减1bit,训练一些steps就减1bit,直至减至8bit INT; 2. (可选,不一定非用&a…

Linux-笔记 全志平台镜像中添加git提交号

引言 通过在镜像中某个位置添加git提交号,可以方便排查与追溯是哪个提交编译出来的。 这里使用的全志T113平台,SDK为Tina5.0。 实现的办法有: 1、内核/proc/cpuinfo的打印信息及设备树中查看提交号 2、从设备树查看提交号 3、从uboot启动…

代码随想录-Day29

491. 非递减子序列 给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-25 多点电容触摸屏实验

前言: 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

双重循环、多重循环程序设计

双重循环格式: for(循环条件1){ 语句1; for(循环条件2){ 语句2; } } 例题1:输入一个整数n,输出一个n层的*三角形塔(完成例1)。 输入样例:6 输出样例: * ** *** **…

Codeforces Global Round 26

Codeforces Global Round 26 Codeforces Global Round 26 A. Strange Splitting 题意:非空数组的范围定义为该数组的最大值减去最小值,现在给出长度大于 n n n的整数数组 a a a,将其分成两组,每组至少一个元素,且两…

13DHCP 原理与配置

目录 2.1 DHCP工作原理 1、了解DHCP服务 2、使用DHCP的好处 3、DHCP的分配方式 4、DHCP的租约过程 2.2 使用 DHCP动态配置主机地址 2.2.1 配置DHCP服务器 1、安装DHCP服务器软件 2、建立主配置文件dhcpd.conf 3、 启动dhcpd服务 2.2.2 使用DHCP客户端 2.3 D…

WPS JSA 宏脚本入门和样例

1入门 WPS window版本才支持JSA宏的功能。 可以自动化的操作文档中的一些内容。 参考文档: WPS API 参考文档:https://open.wps.cn/previous/docs/client/wpsLoad 微软的Word API文档:Microsoft.Office.Interop.Word 命名空间 | Microsoft …