相关文章推荐
腹黑的弓箭  ·  Nine-year ...·  2 月前    · 
还单身的充电器  ·  丁克(暨南大学药学院院长、教授)_百度百科·  6 月前    · 
逃跑的键盘  ·  任鑫 - ...·  1 年前    · 
无邪的煎饼  ·  四本连刷N遍都不腻的网络小说,读者:不看完我 ...·  1 年前    · 
飘逸的感冒药  ·  驻哥斯达黎加大使汤恒出席哥企业集团创新流程管 ...·  2 年前    · 
Code  ›  番外篇: 仿射变换与透视变换开发者社区
矩阵 变换矩阵 透视变换 仿射变换
https://cloud.tencent.com/developer/article/1913564
活泼的石榴
1 年前
CodecWang

番外篇: 仿射变换与透视变换

前往小程序,Get 更优 阅读体验!
立即前往
腾讯云
开发者社区
文档 建议反馈 控制台
首页
学习
活动
专区
工具
TVP
最新优惠活动
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
CodecWang
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
社区首页 > 专栏 > 番外篇: 仿射变换与透视变换

番外篇: 仿射变换与透视变换

作者头像
CodecWang
发布 于 2021-12-07 15:00:59
1.8K 0
发布 于 2021-12-07 15:00:59
举报
文章被收录于专栏: CodecWang

常见的2D图像变换从原理上讲主要包括基于2×3矩阵的 仿射变换 和基于3×3矩阵 透视变换 。

仿射变换

基本的图像变换就是二维坐标的变换:从一种二维坐标(x,y)到另一种二维坐标(u,v)的线性变换:

如果写成矩阵的形式,就是:

作如下定义:

矩阵T(2×3)就称为仿射变换的变换矩阵,R为线性变换矩阵,t为平移矩阵,简单来说,仿射变换就是线性变换+平移。变换后直线依然是直线,平行线依然是平行线,直线间的相对位置关系不变,因此 非共线的三个对应点便可确定唯一的一个仿射变换 ,线性变换4个自由度+平移2个自由度→ 仿射变换自由度为6 。

来看下OpenCV中如何实现仿射变换:

代码语言: javascript
复制
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('drawing.jpg')
rows, cols = img.shape[:2]
# 变换前的三个点
pts1 = np.float32([[50, 65], [150, 65], [210, 210]])
# 变换后的三个点
pts2 = np.float32([[50, 100], [150, 65], [100, 250]])
# 生成变换矩阵
M = cv2.getAffineTransform(pts1, pts2)
dst = cv2.warpAffine(img, M, (cols, rows))
plt.subplot(121), plt.imshow(img), plt.title('input')
plt.subplot(122), plt.imshow(dst), plt.title('output')
plt.show()Copy to clipboardErrorCopied

三个点我已经在图中标记了出来。用 cv2.getAffineTransform() 生成变换矩阵,接下来再用 cv2.warpAffine() 实现变换。

思考:三个点我标记的是红色,为什么Matplotlib显示出来是下面这种颜色?( 练习 )

仿射变换前后对比图
仿射变换前后对比图

其实平移、旋转、缩放和翻转等变换就是对应了不同的仿射变换矩阵,下面分别来看下。

平移

平移就是x和y方向上的直接移动,可以上下/左右移动,自由度为2,变换矩阵可以表示为:

旋转

旋转是坐标轴方向饶原点旋转一定的角度θ,自由度为1,不包含平移,如顺时针旋转可以表示为:

思考:如果不是绕原点,而是可变点,自由度是多少呢?(请看下文刚体变换)

翻转

翻转是x或y某个方向或全部方向上取反,自由度为2,比如这里以垂直翻转为例:

刚体变换

旋转+平移也称刚体变换(Rigid Transform),就是说如果 图像变换前后两点间的距离仍然保持不变 ,那么这种变化就称为刚体变换。刚体变换包括了平移、旋转和翻转,自由度为3。变换矩阵可以表示为:

由于只是旋转和平移,刚体变换保持了直线间的长度不变,所以也称欧式变换(变化前后保持欧氏距离)。

缩放

缩放是x和y方向的尺度(倍数)变换,在有些资料上非等比例的缩放也称为拉伸/挤压,等比例缩放自由度为1,非等比例缩放自由度为2,矩阵可以表示为:

相似变换

相似变换又称缩放旋转,相似变换包含了旋转、等比例缩放和平移等变换,自由度为4。在OpenCV中,旋转就是用相似变换实现的:

若缩放比例为scale,旋转角度为θ,旋转中心是 \(center\_x,center\_y\) ,则仿射变换可以表示为:

其中,

相似变换相比刚体变换加了缩放,所以并不会保持欧氏距离不变,但直线间的夹角依然不变。

经验之谈:OpenCV中默认按照逆时针旋转噢~

总结一下( 原图[#计算机视觉:算法与应用p39] ):

变换

矩阵

自由度

保持性质

平移

[I, t](2×3)

2

方向/长度/夹角/平行性/直线性

刚体

[R, t](2×3)

3

长度/夹角/平行性/直线性

相似

[sR, t](2×3)

4

夹角/平行性/直线性

仿射

[T](2×3)

6

平行性/直线性

透视

[T](3×3)

8

直线性

透视变换

前面仿射变换后依然是平行四边形,并不能做到任意的变换。

透视变换 (Perspective Transformation)是将二维的图片投影到一个三维视平面上,然后再转换到二维坐标下,所以也称为投影映射(Projective Mapping)。简单来说就是二维→三维→二维的一个过程。

这次我写成齐次矩阵的形式:

其中, \left\[ \begin{matrix} a\_1 & b\_1 \newline a\_2 & b\_2 \newline \end{matrix} \right\] 表示线性变换, \left\[ \begin{matrix} a\_3 & b\_3 \end{matrix} \right\] 产生透视变换,其余表示平移变换,因此仿射变换是透视变换的子集。接下来再通过除以Z轴转换成二维坐标:

透视变换相比仿射变换更加灵活,变换后会产生一个新的四边形,但不一定是平行四边形,所以需要 非共线的四个点才能唯一确定 ,原图中的直线变换后依然是直线。因为四边形包括了所有的平行四边形,所以透视变换包括了所有的仿射变换。

OpenCV中首先根据变换前后的四个点用 cv2.getPerspectiveTransform() 生成3×3的变换矩阵,然后再用 cv2.warpPerspective() 进行透视变换。实战演练一下:

矫正一鸣的卡片
矫正一鸣的卡片
代码语言: javascript
复制
img = cv2.imread('card.jpg')
# 原图中卡片的四个角点
pts1 = np.float32([[148, 80], [437, 114], [94, 247], [423, 288]])
# 变换后分别在左上、右上、左下、右下四个点
pts2 = np.float32([[0, 0], [320, 0], [0, 178], [320, 178]])
# 生成透视变换矩阵
M = cv2.getPerspectiveTransform(pts1, pts2)
 
推荐文章
腹黑的弓箭  ·  Nine-year schools_Longgang District-Shenzhen Government Online
2 月前
还单身的充电器  ·  丁克(暨南大学药学院院长、教授)_百度百科
6 月前
逃跑的键盘  ·  任鑫 - Get创始人&前今夜酒店特价创始人 | 到「在行」来约见我
1 年前
无邪的煎饼  ·  四本连刷N遍都不腻的网络小说,读者:不看完我会舍不得睡_百科TA说
1 年前
飘逸的感冒药  ·  驻哥斯达黎加大使汤恒出席哥企业集团创新流程管理研修班开班仪式
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号