cv基础组队学习

计算机视觉基础:图像处理(上)

task2 几何变换

该部分将对基本的几何变换进行学习,几何变换的原理大多都是相似,只是变换矩阵不同,因此,我们以最常用的平移和旋转为例进行学习。在深度学习领域,我们常用平移、旋转、镜像等操作进行数据增广;在传统CV领域,由于某些拍摄角度的问题,我们需要对图像进行矫正处理,而几何变换正是这个处理过程的基础,因此了解和学习几何变换也是有必要的。

这次我们带着几个问题进行,以旋转为例:

1:变换的形式(公式)是什么?

2:旋转中心是什么?

3:采用前向映射还是反向映射?

4:采用反向映射后,采用何种插值算法?

学习目标

  • 了解几何变换的概念与应用

  • 理解平移、旋转的原理

  • 掌握在OpenCV框架下实现平移、旋转操作

内容

1.1变换形式
根据冈萨雷斯书中的描述,仿射变换的一般形式如下:
在这里插入图片描述

式中的T就是变换矩阵,其中 (v,w)为原坐标,(x,y) 为变换后的坐标,一些常见的变换矩阵及作用如下表:
在这里插入图片描述
opencv中提供了相应API进行图像的平移、旋转、仿射:

cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])
src - 输入图像。
M - 变换矩阵。
dsize - 输出图像的大小。
flags - 插值方法的组合(int 类型!)
borderMode - 边界像素模式(int 类型!)
borderValue - 边界填充值; 默认情况下,它为0。

关于最后一个参数,在图像上效果是这样的:
在这里插入图片描述
边界被填充了黑色,往往会给后续处理数据造成困扰,修改borderValue=(255,255,255):

在这里插入图片描述
如果明白矩阵相乘和图像变换的原理,可以手动设置变换矩阵,同时opencv也提供函数帮助我们更快找到变换矩阵:

//得到旋转矩阵
cv2.getRotationMatrix2D(center, angle, scale)
center:图片的旋转中心
angle:旋转角度
scale:缩放比例

//得到仿射矩阵
cv.GetAffineTransform(src, dst, mapMatrix) 
src:原始图像中的三个点的坐标
dst:变换后的这三个点对应的坐标

通过三个点就能得到图像关系的矩阵:
三个点
根据上述矩阵对图像进行变换:

##恒等变换
    m1 = np.float32([[1, 0, 1], [0, 1, 0]])
    ##尺度变换
    m2 = np.float32([[2, 0, 0], [0, 1, 0]])
    ##旋转变换
    m3 = cv2.getRotationMatrix2D((cols / 2, rows / 2), 90, 1)  ##逆时针方向
    ##平移变换
    m4 = np.float32([[1, 0, 200], [0, 1, 1]])
    ##偏移变换
    m5 = np.float32([[1, 0.2, 0], [0, 1, 0]])
    m6 = np.float32([[1, 0, 0], [0.2, 1, 0]])
    tra1 = cv2.warpAffine(img, m1, (cols, rows))
    tra2 = cv2.warpAffine(img, m2, (cols, rows))
    tra3 = cv2.warpAffine(img, m3, (cols, rows))
    tra4 = cv2.warpAffine(img, m4, (cols, rows))
    tra5 = cv2.warpAffine(img, m5, (cols, rows))
    tra6 = cv2.warpAffine(img, m6, (cols, rows), borderValue=(255, 255, 255))
    cv2.imshow("src", img)
    cv2.imshow("tra1", tra1)
    cv2.imshow("tra2", tra2)
    cv2.imshow("tra3", tra3)
    cv2.imshow("tra4", tra4)
    cv2.imshow("tra5", tra5)
    cv2.imshow("tra6", tra6)
    cv2.waitKey()

在这里插入图片描述
1.2坐标系变换
变换中心,对于缩放、平移可以以图像坐标原点(图像左上角为原点)为中心变换,这不用坐标系变换,直接按照一般形式计算即可。而对于旋转和偏移,一般是以图像中心为原点,那么这就涉及坐标系转换了。

我们都知道,图像坐标的原点在图像左上角,水平向右为 X 轴,垂直向下为 Y 轴。数学课本中常见的坐标系是以图像中心为原点,水平向右为 X 轴,垂直向上为 Y 轴,称为笛卡尔坐标系。看下图:
Image
因此,对于旋转和偏移,就需要3步(3次变换):

  • 将输入原图图像坐标转换为笛卡尔坐标系;
  • 进行旋转计算。旋转矩阵前面已经给出了;
  • 将旋转后的图像的笛卡尔坐标转回图像坐标。

图像坐标系与笛卡尔坐标系转换关系:

Image

在图像中我们的坐标系通常是AB和AC方向的,原点为A,而笛卡尔直角坐标系是DE和DF方向的,原点为D。
令图像表示为M×N的矩阵,对于点A而言,两坐标系中的坐标分别是(0,0)和(-N/2,M/2),则图像某像素点(x’,y’)转换为笛卡尔坐标(x,y)转换关系为,x为列,y为行:

Image

逆变换为:

Image

于是,根据前面说的3个步骤(3次变换),旋转(顺时针旋转)的变换形式就为,3次变换就有3个矩阵:

Image
1.3 反向映射

向前映射法

  可以将几何运算想象成一次一个象素地转移到输出图象中。如果一个输入象素被映射到四个输出象素之间的位置,则其灰度值就按插值算法在4个输出象素之间进行分配。称为向前映射法,或象素移交影射。

输入图像上整数点坐标映射到输出图像之后,变成了非整数点坐标。因此,需要将其像素值按一定权重分配到其周围四个像素点上。对于输出图像而言,其整数点像素值周围会有很多输入图像像素映射过来,每个到其周围的非整数点像素值都会分配一定的灰度值到它上面,将这些分配而来的像素值叠加,就是输出图像整数点位置的像素值。
在这里插入图片描述
对于向前映射而言,输出图像某一点的像素值不能直接得到,需要遍历输入图像的所有像素值,对其进行坐标变换,分配像素值到整数位置,才能得到输出图像各像素点的像素值。这是向前映射法的缺点

向后映射法

  向后映射法(或象素填充算法)是输出象素一次一个地映射回到输入象素中,以便确定其灰度级。如果一个输出象素被映射到4个输入象素之间,则其灰度值插值决定,向后空间变换是向前变换的逆。
在这里插入图片描述

我们知道输出图像上整数点位置(x’,y’)在变换前位于输入图像上的位置(x,y),一般来说这是个非整数点位置,利用其周围整数点位置的输入图像像素值进行插值,就得到了该点的像素值。我们遍历输出图像,经过坐标变换、插值两步操作,我们就能将其像素值一个个地计算出来。

在冈萨雷斯的《数字图像处理_第三版》中说的很清楚,前向映射就是根据原图用变换公式直接算出输出图像相应像素的空间位置,那么这会导致一个问题:可能会有多个像素坐标映射到输出图像的同一位置,也可能输出图像的某些位置完全没有相应的输入图像像素与它匹配,也就是没有被映射到,造成有规律的空洞(黑色的蜂窝状)。更好的是采用 反向映射(Inverse Mapping)。

1.4 插值方法
opencv中默认采用双线性插值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值