DataWhale 机器视觉组队学习task2
2.1 简介
该部分将对基本的几何变换进行学习,几何变换的原理大多都是相似,只是变换矩阵不同,因此,我们以最常用的平移和旋转为例进行学习。在深度学习领域,我们常用平移、旋转、镜像等操作进行数据增广;在传统CV领域,由于某些拍摄角度的问题,我们需要对图像进行矫正处理,而几何变换正是这个处理过程的基础,因此了解和学习几何变换也是有必要的。
这次我们带着几个问题进行,以旋转为例:
-
1:变换的形式(公式)是什么?
-
2:旋转中心是什么?毕竟以不同位置为旋转中心得到的结果是不一样的。
-
3:采用前向映射还是反向映射?(反向映射更为有效)
-
4:采用反向映射后,采用何种插值算法?最常用的的是双线性插值,OpenCV也是默认如此。
2.2 学习目标
-
了解几何变换的概念与应用
-
理解平移、旋转的原理
-
掌握在OpenCV框架下实现平移、旋转操作
2.3 内容介绍
1、平移、旋转的原理
2、OpenCV代码实践
3、动手实践并打卡(读者完成)
2.4 算法理论介绍
2.4.1 向前映射与向后映射
前向映射:
图像的几何变换就是建立一种源图像像素与变换后的图像像素之间的映射关系。也正是通过这种映射关系可以知道原图像任意像素点变换后的坐标,或者是变换后的图像在原图像的坐标位置等。
用简单的数学公式可以表示为:
( x y ) = ( U ( u , v ) V ( u , v ) ) f ( u , v ) = ( x , y ) \begin{pmatrix}x\\y\end{pmatrix}=\begin{pmatrix}U(u,v)\\V(u,v)\end{pmatrix}\\ f(u,v)=(x,y) (xy)=(U(u,v)V(u,v))f(u,v)=(x,y)
其中, x x x, y y y代表输出图像像素的坐标, u u u, v v v表示输入图像的像素坐标,而 U U U, V V V表示的是两种映射关系, f f f是将点 ( u , v ) (u,v) (u,v)映射到 ( x , y ) (x,y) (x,y)的映射关系,需要说明的是,映射关系可以是线性关系,也可以是多项式关系
从上面的映射关系可以看到,只要给出了图像上任意的像素坐标,都能够通过对应的映射关系获得几何变换后的像素坐标。这种将输入映射到输出的过程我们称之为 “向前映射”。但是在实际应用中,向前映射会出现如下几个问题:
-
浮点数坐标,如(1,1)映射为(0.5,0.5),显然这是一个无效的坐标,这时我们需要使用插值算法进行进一步处理。
-
可能会有多个像素坐标映射到输出图像的同一位置,也可能输出图像的某些位置完全没有相应的输入图像像素与它匹配,也就是没有被映射到,造成有规律的空洞(黑色的蜂窝状)。
什么是有规律的空洞呢?下面举个例子大家就明白了
可以从上图知道:原图经过前向映射旋转了30度后,输出图像中有规律的空洞(黑色的蜂窝状),那这些空洞是这么来的呢?
可以看到,旋转三十度后,输出图像两个红色的点被映射到同一个坐标,而没有点被映射到绿色问号处,这就造成了间隙和重叠,导致出现蜂窝状空洞。
向后映射
为了克服前向映射的这些不足,因此引进了“后向映射”
它的数学表达式为:
( u v ) = ( U − 1 ( x , y ) V − 1 ( x , y ) ) f − 1 ( x , y ) = ( u , v ) \begin{pmatrix}u\\v\end{pmatrix}=\begin{pmatrix}U^{-1}(x,y)\\V^{-1}(x,y)\end{pmatrix} \\ f^{-1}(x,y)=(u,v) (uv)=(U−1(x,y)V−1(x,y))f−1(x,y)=(u,v)
可以看出,后向映射与前向映射刚好相反,它是由输出图像的像素坐标反过来推算该像素为在源图像中的坐标位置。这样,输出图像的每个像素值都能够通过这个映射关系找到对应的为止。而不会造成上面所提到的映射不完全和映射重叠的现象。在实际处理中基本上都运用向后映射来进行图像的几何变换。但是反向映射也有一个和前向映射一样的问题, 就是映射后会有小数,需通过插值方法决定输出图像该位置的值,OpenCV默认为双线性插值。
在使用过程中,如果在一些不改变图像大小的几何变换中,向前映射还是十分有效的,向后映射主要运用在图像的旋转的缩放中,因为这些几何变换都会改变图像的大小。
2.4.1 几何变换
先看第一个问题,变换的形式。在本篇文章里图像的几何变换全部都采用统一的矩阵表示法,形式如下:
[ x y 1 ] = [ a 0 a 1 a 2 a 3 a 4 a 5 0 0 1 ] [ x 0 y 0 1 ] \begin{bmatrix}x \\y\\1\end{bmatrix} =\begin{bmatrix} a_0 &a_1 & a_2 \\ a_3 & a_4 & a_5 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x_0 \\ y_0 \\ 1 \end{bmatrix} ⎣⎡xy1⎦⎤=⎣⎡a0a30a1a40a2a51⎦⎤⎣⎡x0y01⎦⎤
这就是向前映射的矩阵表示法,其中 x x x, y y y表示输出图像像素的坐标, x 0 x_0 x0, y 0 y_0 y0表示输入图像像素的坐标,同理,向后映射的矩阵表示为:
[ x 0 y 0 1 ] = [ b 0 b 1 b 2 b 3 b 4 b 5 0 0 1 ] [ x y 1 ] \begin{bmatrix}x_0 \\y_0\\1\end{bmatrix} =\begin{bmatrix} b_0 &b_1 & b_2 \\ b_3 & b_4 & b_5 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} ⎣⎡x0y01⎦⎤=⎣⎡b0b30b1b40b2b51⎦⎤⎣⎡xy1⎦⎤
可以证明,向后映射的矩阵的表示正好是向前映射的逆变换。
变换名称 | a 0 a_0 a0 | a 1 a_1 a1 | a 2 a_2 a2 | a 3 a_3 a3 | a 4 a_4 a |
---|