三维错切变换矩阵_图像的仿射变换

目录:

  1. 概述
  2. 图像基本变换
  3. 仿射变换
    1. 原理
    2. python实现

一、概述

图像的几何变换主要包括:平移、缩放、旋转、仿射、透视等等。图像变换是建立在矩阵运算基础上的,通过矩阵运算可以很快的找到不同图像的对应关系。理解变换的原理需要理解变换的构造方法以及矩阵的运算方法。

图像的几何变换主要分为三类:刚性变换、仿射变换和透视变换,如下图:

b4ccf0897d9192b16d7c731bafa3f974.png

仿射变换是从一个二维坐标系变换到另一个二维坐标系,属于线性变换。通过已知3对坐标点可以求得变换矩阵。

透视变换是从一个二维坐标系变换到一个三维坐标系,属于非线性变换。通过已知4对坐标点可以求得变换矩阵。

二、图像基本变换

图像的几何变换包含很多变换,其中有一些基本变换,而仿射变换和透视变换就是对这些基本变换进行组合实现的。

基本变换具体包括:平移(Translation)、缩放(Scale)、旋转(Rotation)、翻转(Flip)和错切(Shear)。

a. 平移

b87e6b80957bf827b02f0a0778bf2ee9.png

84c897b079c54ccbaa6d09a8f495fd08.png

b. 缩放

b4301d563483f14258d1b0b2c232ea22.png

8e81442a9bf989f3406b4065d92e7620.png

c. 旋转

766408a81d986bbdf62b70f5d00a8306.png

a25aa3b949d4ea1afed0a9f15f5b81a9.png

d. 翻转

e0c14e6346a09ebb7405cd5436b5e841.png

9b7471ec6fc16c28470d99b73930aa89.png

e. 错切

错切亦称为剪切或错位变换,包含水平错切和垂直错切,常用于产生弹性物体的变形处理。

2d114d79fc2d9a3aa78908249e344176.png

fcaeeccb70d0a718b80a245e84de5f54.png

3538d798ea2b9d591062f2c21d818e4d.png

下面这张图可能更形象:

1e55537ba13858865644136d5e7dd71c.png

三、仿射变换

3.1、原理

对于二维坐标系的一个坐标点(x,y),可以使用一个2x2矩阵来调整x,y的值,而通过调整x,y可以实现二维形状的线性变换(旋转,缩放),所以整个转换过程就是对(x,y)调整的过程。

仿射变换(Affine Transformation)是指在向量空间中进行一次线性变换(乘以一个矩阵)和一次平移(加上一个向量),变换到另一个向量空间的过程。

仿射变换代表的是两幅图之间的映射关系,仿射变换矩阵为2x3的矩阵,如下图中的矩阵M,其中的B起着 平移 的作用,而A中的对角线决定 缩放,反对角线决定 旋转错切

所以仿射变换可以由一个矩阵A和一个向量B给出:

原像素点坐标(x,y),经过仿射变换后的点的坐标是T,则矩阵仿射变换基本算法原理:

所以仿射变换是一种二维坐标(x, y)到二维坐标(u, v)的线性变换,其数学表达式如下:

其实到这里还没完,我们知道缩放和旋转通过矩阵乘法来实现,而平移是通过矩阵加法来实现的,为了将这几个操作都通过一个矩阵来实现,所以构造出了上面那个 2x3 的矩阵。

但是这个会改变图像的尺寸,比如一个 2x2 的图像,乘以 2x3 的矩阵,会得到 2x3 的图像,所以为了解决这个问题,我们就增加一个维度,也就是构造齐次坐标矩阵。

关于齐次坐标的更多内容可以查看这里,还有这里。

最终得到的齐次坐标矩阵表示形式为:

仿射变换保持了二维图像的“平直性”和“平行性”:

平直性:

  • 直线经仿射变换后还是直线
  • 圆弧经仿射变换后还是圆弧

平行性:

  • 直线之间的相对位置关系保持不变
  • 平行线经仿射变换后依然为平行线
  • 直线上点的位置顺序不会发生变化
  • 向量间夹角可能会发生变化

3.2、python实现

通过仿射变换将图片中的每个像素点按照一定的规律映射到新的位置,仿射变化需要一个转换矩阵,但是由于仿射变换比较复杂,一般很难直接找到这个矩阵,opencv提供了根据源图像和目标图像上三个对应的点来自动创建变换矩阵,矩阵维度为 2x3。

7b9b82329a70212b93104987178a7024.png

两个图像中非共线的三对对应点确定唯一的一个仿射变换。经仿射变换后,图像中的三个关键点依然构成三角形,但三角形形状已经发生变化。

这个函数是 cv2.getAffineTransform(pos1,pos2),其中两个位置就是变换前后的对应位置关系。输出的就是仿射矩阵M,最后这个矩阵会被传给函数 cv2.warpAffine() 来实现仿射变换。

原图为:

4c61bbb1ae5e0d374b31bdc45ac27760.png
import cv2
import numpy as np
img = cv2.imread('image0.jpg', 1)
height, width = img.shape[:2]  # 405x413
# 在原图像和目标图像上各选择三个点
matSrc = np.float32([[0, 0],[0, height-1],[width-1, 0]])
matDst = np.float32([[0, 0],[30, height-30],[width-30, 30]])
# 得到变换矩阵
matAffine = cv2.getAffineTransform(matSrc, matDst)
# 进行仿射变换
dst = cv2.warpAffine(img, matAffine, (width,height))

变换矩阵的数据类型是 np.float32,函数 cv2.warpAffine() 的第三个参数是输出图像的尺寸(宽,高)。

仿射变换后的图:

2aa5142e05da5ef640cebb207192f5e9.png

因为平移和缩放的矩阵的比较简单,我们可以直接手动指定。

# 图像平移
# 移位矩阵,水平方向移动100个像素,竖直方向移动200个像素
matShift = np.float32([[1,0,100],[0,1,200]])  # 2行3列
dst = cv2.warpAffine(img, matShift, (width,height))
# 图像缩放
# 缩放矩阵,长宽各缩放一半
matScale = np.float32([[0.5,0,0],[0,0.5,0]])
dst = cv2.warpAffine(img, matScale, (int(width/2),int(height/2)))

向左下平移:

044112d8b6539b3eea390e5f6e4df8cf.png

缩小50%:

d4b22761c268cc34c1dd9c8c12cbdf17.png

要实现图像旋转,需要通过 cv2.getRotationMatrix2D 来得到二维旋转变换矩阵(2行3列)。

cv2.getRotationMatrix2D 三个参数分别为:1.旋转中心,2.旋转角度,3.缩放比例。角度为正,则图像逆时针旋转,旋转后图像可能会超出边界。

matRotate = cv2.getRotationMatrix2D((width*0.5, height*0.5), 45, 1.0)
dst = cv2.warpAffine(img, matRotate, (width,height))

f581b4fc58ca166090bb31d17ba99de4.png

如果觉得有用,点个赞吧(ง •̀_•́)ง。

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

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

相关文章

app系统服务器出错怎么回事,app连接服务器出错

app连接服务器出错 内容精选换一换接口调用出错将无法获取建立相应隧道连接的必要信息,将无法正常建连云手机设备实例,具体报错示例如下:首先,尝试使用adb connect重新建立连接,依旧报错可通过查看安装目录下的日志adb…

js foreach 跳出循环_VUE.js

Vue.js模板语法vue.js使用了基于HTML的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据,其核心就是一个允许开发者采用简洁的模板语法来将数据渲染进DOM系统。使用各种组件来做成一个项目的话,需要结合单页应用。插值数据绑定最…

2异常处理_异常是什么?什么是常用类?

第一节 异常1. 异常的概念​ 异常(Exception) 即例外,程序没有按自己预想的结果运行出来,出现了非正常情况,即“程序得病了”。怎么让我们写的程序做出合理的处理,不至于崩溃是我们关注的核心。 异常机制就是当程序出现错误&#…

origin三元相图_扩增子图表解读7三元图:三组差异数量和关系

点击上方蓝色「宏基因组」关注我们!专业干货每日推送!背景介绍(Introduction)宏基因组学宏基因组学目前的主要研究方法包括:16S/ITS/18S扩增子、宏基因组、宏转录组和代谢组,其中以扩增子研究最为广泛。目的意义本系列文章将带领大…

写出python字符串三种常用的函数或方法_python中几种常用字符串函数

1、lower()把所有字符换成小写 2、upper()把所有字符换成大写 3、swapcase()大小写互换 4、title()把每个单词首字母大写,他是以所有英文字母的字符来区别是否为一个单词的,eg:s "a是傻b" s2 s.title() 结果为"A傻B",a和b都变成了大写,因为他是根据英文字…

python app开发模块_Python pytkapp包_程序模块 - PyPI - Python中文网

用于开发应用程序的python包 多文档/单文档界面 利用tkinter库和附加tkinter集 小部件。 查看可用演示: pytkapp/demo/run_ptapoptionsdemo.py-为选项的容器运行gui demo(可用的小部件、规则) pytkapp/demo/run_ptamdidemo.py-运行MDI应用程序…

搭建python_Crawlab准备之python+scrapy环境搭建

阅读文本大概需要3分钟。上篇《分布式爬虫管理平台Crawlab开发搭建》把爬虫的管理后台搭建起来了;捣鼓一番发现要真正爬取数据还有下不少的功夫。这篇看看怎么搭建pythonscrapy环境。0x01:安装Python3下载python安装包,具体版本根据自己的系统…

64测试cpu稳定性_SuperPI-圆周率计算与CPU性能与稳定性测试

Super PI是由东京大学Kanada lab出品的一款专用于检测CPU稳定性的软件,目前最新版本是1.9版,更新于2013年了。Super PI软件通过计算预定的圆周率让CPU高负荷运作,从而达到考验CPU计算的能力与稳定的作用。同时也能计算出圆周率来保存到文本文…

python对比两个文件找出不同并显示_python difflib模块实现两个文件差异对比,并输出html格式。...

difflib 模块包含一些用来计算和处理序列之间差异的工具。它对于比较文本尤其有用,其中包含的函数可以使用多种常用差异格式生成报告。 实现了三个类: SequenceMatcher 任意类型序列的比较 (可以比较字符串) Differ 对字符串进行比较 HtmlDiff 将比较结果…

传值类型_java中的“传值”与“传址”问题

“用对象来生成对象”“对象作为参数进行传递”“构造方法中的参数为对象”问题本质上是“传值”与“传址”的问题先说结论:1、基本类型(包括String类)作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝&#xff…

python可以处理wps吗_基于python的docx模块处理word和WPS的docx格式文件方式

基于python的docx模块处理word和WPS的docx格式文件方式 发布时间:2020-08-23 05:37:05 来源:脚本之家 阅读:109 Python docx module for Word or WPS processing 本文是通过docx把word中的表格中的某些已填好的内容提取出来,存入e…

两个苹果手机如何同步数据_同步苹果手机和Windows的提醒事项

作为一个学生党,能买得起苹果手机已经是一件很幸福的事情了,拥有苹果电脑只是一个美好的愿望,所以现在常见的搭配就是苹果手机加Window电脑,这样就有一个问题,就是苹果手机和Windows电脑的提醒事项没有办法同步&#x…

低通滤波器算法实现_控制算法手记自抗扰控制的几点思考

写在前面在谈自己的一些思考之前,放上一本简明的教材(只有133页),对自抗扰控制ADRC (Active disturbance rejection control)的起源、基本思路、结构、发展及应用做了阐述,是很好的入门读物。图1. 自抗扰控制入门书籍如果要达到弄懂&#xff…

添加日志_第五章springboot2.0添加aop日志实现记录请求地址

1. 添加spring-boot-starter-aop包<dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-aopartifactId><version>2.0.0.RELEASEversion>dependency>2. 新建WebLogAspect类3. 添加Aspect Component注解…

本机连接opc server有部分数据不刷新_实时数据库PI在企业MES系统中的应用

实时数据库是计算机控制系统和上层生产管理系统数据存储和展示的核心。结合河南天冠燃料乙醇有限公司MES系统应用实例&#xff0c;介绍了实时数据库PI的安装部署&#xff0c;建立信号量集和数据导入&#xff0c;以及客户端接口配置&#xff0c;数据库测试等相关主题。通过基于P…

pythonlistsort函数_python用List的内建函数list.sort进行排序

对List进行排序&#xff0c;Python提供了两个方法方法1.用List的内建函数list.sort进行排序list.sort(funcNone, keyNone, reverseFalse)Python实例&#xff1a;方法2.用序列类型函数sorted(list)进行排序(从2.4开始)Python实例&#xff1a;两种方法的区别&#xff1a;sorted(l…

java 数组赋值_自学JAVA每日记录(10)-欢迎指点欢迎共勉

接上一篇编程练习&#xff1a;编写一个JAVA程序&#xff0c;创建指定长度的 int 型数组&#xff0c;并生成 100 以内随机数为数组中的每个元素赋值&#xff0c;然后输出数组要求&#xff1a;1、 要求通过定义带参带返回值的方法来实现2、 通过参数传入数组的长度&#xff08;例…

agv系统介绍_AGV地面控制系统介绍

AGV控制系统分为地面(上位)控制系统、车载(单机)控制系统及导航/导引系统&#xff0c;其中&#xff0c;地面控制系统指AGV系统的固定设备&#xff0c;主要负责任务分配&#xff0c;车辆调度&#xff0c;路径(线)管理&#xff0c;交通管理&#xff0c;自动充电等功能&#xff1b…

python爬虫绕过验证码_爬虫怎样绕过验证码?

叶湘伦&#xff1a;【文字篇】如何系统地自学 Python&#xff1f;​zhuanlan.zhihu.com1&#xff0c;cookie登录利用cookie的特性&#xff1a;cookie会保持较长的时间&#xff0c;来避免用户频繁登录cookie一般由前端开发用js生成&#xff0c;可以利用抓包尝试下破解&#xff0…

python数据变更邮件提醒_如何使python脚本在某些数据更改时自动发送电子邮件?...

所以基本上&#xff0c;我做了一个python脚本&#xff0c;每12小时给我发送一封包含我公共IP地址的电子邮件。我的目标是使它自动发送电子邮件只有当我的IP更改。如果我能帮上忙的话。在我的密码是&#xff1a;from json import loadsfrom urllib.request import urlopenimport…