【Opencv每周实例练习】03 -仿射变换和透视变换

一、目的

  • 这两个知识点平时还是比较常见
  • 它可以顺带的理解一下图像的缩放、平移等等
  • 对3x3矩阵的妙用希望略懂皮毛

二、公式推导

2.1 平面矩阵

这儿只定义平面的操作。
在这里插入图片描述
就拿平移矩阵为例,这个表示什么意思呢?
可以看到,公式里面只有坐标x,y;但是我们要的是像素值啊!!
这个矩阵表示的是平移前像素位置,平移后应该在哪个位置。看代码应该一目了然了。

move_mat = np.array([[1, 0,  a], [0 , 1, b], [0 , 0 , 1]])
image = cv2.imread("img.png")
new_img = np.zeros(image.shape)
for i in range(img.shape[0]):
	for j in range(img.shape[1])):
		tem_xy = [[i],[j],[1]]
		new_tem_xy = np.matmul(move_mat, tem_xy)
		if new_tem_xy[0][0] <= image.shape[1] & new_tem_xy[1][0] <= image.shape[0] /
			& new_tem_xy[0][0]>=0 &new_tem_xy[1][0] >= 0:
				new_img[new_tem_xy[1][0]][new_tem_xy[0][0]] = image[i][j]		

可以看到,它是求出映射后 的x,y的值,然后把原来x,y处的像素值赋值给这个位置。

2.2 错切

如下图,矩形关于y方向的错切:
在这里插入图片描述
数学表达式为
在这里插入图片描述
那么x轴上的错切也是同理:
在这里插入图片描述
x轴和y轴合起来,就可以由如下表示:
在这里插入图片描述

2.3 仿射变换

仿射变换是由平移+ 旋转 + 缩放 + 错切之后得到的。
在这里插入图片描述

2.4 仿射变换和透视变换的区别

在这里插入图片描述
仿射变换(下):是矩形变成了平行四边形(即变换前后各边依旧平行)。
而透视变换(上):变换后是任意不规则的四边形
仿射变换是线性变换。而透视变换不是,可以说仿射变换是透视变换的一种特例

3 仿射变换

3.1 API
void cv::warpAffine     (   InputArray      src,
        OutputArray     dst,
        InputArray      M,
        Size    dsize,
        int     flags = INTER_LINEAR,
        int     borderMode = BORDER_CONSTANT,
        const Scalar &      borderValue = Scalar() 
    )

参数解释
- src: 输入图像
- dst: 输出图像,尺寸由dsize指定,图像类型与原图像一致
- M: 2X3的变换矩阵 ,需要注意的opencv集成的M矩阵是把最后的那一行删掉的哈,留下的是2x3的矩阵
- dsize: 指定图像输出尺寸
- flags: 插值算法标识符,有默认值INTER_LINEAR,如果插值算法为WARP_INVERSE_MAP, warpAffine函数使用如下矩阵进行图像转换
其中,M是最重要的。Opencv也提供了M矩阵的计算API。

getAffineTransform(
	const Point2f* src(),
	const Point2f* dst(),

需要有三对变换前和变换后的点,就可以求到M矩阵了,具体的示例在我的每周练习01里面就有提到。
具体的使用,比如说:我们有斜着的书啊,证件啊啥的,我们想把它转正,怎么办?
转正后的三个角点我们是先验已知的,就是图像的三个边的点。转正前的就可以通过各种手段去标记这个点在当前位置的坐标,之后就可以得到M矩阵,然后通过仿射变换API就可以得到正向的书了。
在这里插入图片描述
如这本斜置的书,我们认为的用鼠标找到书的四个角的像素点位置,然后去映射到正向图像的(0,0);(0,w);(h, 0 );(h,w),只需要三点求出M矩阵就行了。

4、透视变换 perspective-transfrom

透视变换同样是一个3x3的矩阵,不过第三行的矩阵现在有变换了。
在这里插入图片描述
上面矩阵的未知量比仿射变换的矩阵多了一个透视变换矩阵T3(两个未知量),因此需要比求解仿射变换多一个位置。也就是说现在要图像的四个点才能求出透视变换的M矩阵。
透视变换API:warpPerspective()

void warpPerspective(
				InputArray src, 输入图像
				OutputArray dst, 输出图像
				InputArray ,M  M矩阵
				Size    dsize,指定图像输出尺寸 
		        int     flags = INTER_LINEAR,
		        int     borderMode = BORDER_CONSTANT,
		        const Scalar &      borderValue = Scalar() )

计算透视变换的M矩阵也有一个单独的API:getPerspectiveTransform()

Mat getPerspectiveTransform(
	const Point2f src[],  输入图像点集
	const Point2f dst[],输出图像点集)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值