【Affine / Perspective Transformation】

news2024/11/16 12:38:20

在这里插入图片描述

文章目录

  • 仿射变换介绍
  • 仿射变换 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单应矩阵实现的

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【话题】评价GPT-4o:从革命性技术到未来挑战

大家好,我是全栈小5,欢迎阅读小5的系列文章,这是《话题》系列文章 目录 引言技术原理应用领域实际案例优势挑战局限性未来展望文章推荐 引言 在人工智能领域,自然语言处理(NLP)技术的进步一直是推动技术革…

odoo15升级odoo16遇到的问题及解决过程

odoo15升级odoo16遇到的问题 PyMuPDF 档案管理整理时,从15升级16出现如下错误: File "f:\od162306\dms\dmssp\models\shenqb.py", line 136, in doc_fj_pdf doc.SaveAs(ftem, FileFormat=17) # input_file.replace(".docx", ".pdf") F…

鸿蒙开发文件管理:【@ohos.environment (目录环境能力)】

目录环境能力 该模块提供环境目录能力,获取内存存储根目录、公共文件根目录的JS接口。 说明: 本模块首批接口从API version 8开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。本模块接口为系统接口,三方应用不支…

Pythone 程序打包成 exe

1.安装pyinstaller # 安装 pip install pyinstaller # 查看版本 pyinstaller -v2.更新pyinstaller 版本 # 更新 pip install --upgrade pyinstaller # 查看版本 pyinstaller -v3.切换到 py文件所在目录 #切换到.py所在的目录 E: cd cd E:\x-svn_x-local\04PythoneProjects\A…

滴滴出行 大数据研发实习生【继任】

大数据研发实习生JD 职位描述 1、负责滴滴核心业务的数据建设,设计并打造适应滴滴一站式出行平台业务特点的数仓体系。 2、负责抽象核心业务流程,沉淀业务通用分析框架,开发数仓中间层和数据应用产品。 3、负责不断完善数据治理体系&#xff…

远程链接服务 ssh

① 指定用户身份登录 ssh root10.36.105.100 ssh jim10.36.105.100 ② 不登陆远程执行命令 ssh root10.36.105.100 ls /opt ③ 远程拷贝 scp -r // 拷贝目录 -p // 指定端口 将本地文件拷贝给远程主机 scp -r /opt/test1 10.36.105.100:/tmp/// 将本…

使用 ML.NET CLI 自动进行模型训练

ML.NET CLI 可为 .NET 开发人员自动生成模型。 若要单独使用 ML.NET API(不使用 ML.NET AutoML CLI),需要选择训练程序(针对特定任务的机器学习算法的实现),以及要应用到数据的数据转换集(特征工程)。 每个数据集的最佳管道各不相同,从所有选择中选择最佳算法增加了复…

轻兔推荐 —— NeatDownloadManager

via:轻兔推荐 - https://app.lighttools.net/ 简介 NeatDownloadManager简称NDM,跟IDM同样出名的网络下载器,安装对应的浏览器器扩展后,可接管浏览器下载 - 软件体积非常小,Windows版900KB,很难想象当今的…

UE5 渲染性能优化 学习笔记

主要考虑三个点: 1、灯光 2、半透明物体 3、后处理 1、Game:CPU对游戏代码的处理工作 2、Draw:CPU为GPU准备数据所做的工作 3、GPU Time:就是GPU所渲染需要花的时间 UE5的命令行指令 里面说明了某个指令有什么用处 以及启动…

隐私计算(1)数据可信流通

目录 1. 数据可信流通体系 2. 信任的基石 3.数据流通中的不可信风险 可信链条的级联失效,以至于崩塌 4.数据内循环与外循环:传统数据安全的信任基础 4.1内循环 4.2外循环 5. 技术信任 6. 密态计算 7.技术信任 7.1可信数字身份 7.2 使用权跨域…

【大数据·hadoop】项目实践:IDEA实现WordCount词频统计项目

一、环境准备 1.1:在ubuntu上安装idea 我们知道,在hdfs分布式系统中,MapReduce这部分程序是需要用户自己开发,我们在ubuntu上安装idea也是为了开发wordcount所需的Map和Reduce程序,最后打包,上传到hdfs上…

贷款业务——LPR、APR、IRR

文章目录 LPR(Loan Prime Rate)贷款市场报价利率APR(Annual Percentage Rate)年化百分比利率IRR(Internal Rate of Return)内部收益率 LPR、APR 和 IRR 是三个不同的金融术语,LPR 是一种市场利率…

Catia装配体零件复制

先选中要复制的零件 然后选中复制到的父节点才可以。 否则 另外一种方法是多实例化

【C++】继承|切片|菱形继承|虚继承

目录 ​编辑 一.什么是继承 三大特性 继承的语法 访问控制 继承的总结 二.继承的作用域 三.切片 四. 派生类的默认成员函数 构造函数 析构函数 拷贝构造 赋值运算符重载 五.单继承和多继承 单继承 多继承 菱形继承 解决方式 六.虚继承 一.什么是继承 C中的…

Excel最基本的常用函数

最基本最常用的函数,掌握了可以解决大部分问题。 (笔记模板由python脚本于2024年06月11日 19:05:56创建,本篇笔记适合熟悉excel的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free:大咖免费“圣…

linux用户态操作GPIO首先需要export导出

在使用系统调用来实现 GPIO(通用输入输出端口)的输入输出操作时,同样需要先通过 export 属性文件来导出 GPIO,这是因为 Linux 内核对 GPIO 的管理和访问机制决定了这一点。 以下是具体原因: 内核设备模型&#xff1a…

加密解密工具免费分享12款,最新文件加密软件排行榜已出炉!

2024年,信息技术的快速发展让我们步入了一个数字化的时代,数据的交换和存储变得异常频繁和庞大。与此同时,数据泄露和盗窃的风险也日益增加,让人们对数据/文件/文件夹传输过程中的安全产生了更深刻的理解和关注。因此,…

vue-cli 快速入门

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

成功解决IndexError: index 0 is out of bounds for axis 1 with size 0

成功解决IndexError: index 0 is out of bounds for axis 1 with size 0 🛠️ 成功解决IndexError: index 0 is out of bounds for axis 1 with size 0摘要引言正文内容(详细介绍)🤔 错误分析:为什么会发生IndexError&…

flask基础知识1

目录 1.介绍 2.体验一下 3.配置参数: 4.路由和URL 1.路由 2.动态路由: 自定义转换器: 3.使用自定义转换器 5.url_for函数 6.request参数 7.处理响应: 1.重定向: 2.返回json数据: 3.返回模板&…