接上一篇:Python 计算机视觉(五)—— OpenCV 进行图像几何变换
目录
1. 应用场景
2. 基本原理
3. 需要的函数
(1) cv2.getPerspectiveTransform()
作用:
参数:
(2) cv2.warpPerspective()
作用:
参数:
4. 实战
我们在生活中常常遇见这种问题:拍了一张照片,但由于不是正对着拍照对象所以拍出的图像只能是一张变形了的照片,这就导致了我们观察图像信息吃力或者拍出的图像不符合某些规范,又或者某一些图像的显示角度出现问题,导致发生形变,在观察的过程中影响了美感,如下面的几张图像所示(图像来源见水印):
上面的几种情况都可以使用透视变换进行修正,来减轻由于角度造成的不好影响
此处参考:【图像处理】透视变换 Perspective Transformation
透视变换就是将原图投影到一个新的视平面中,也被称为投影映射,如下图:
从上图可以看出,选取合适的投影中心和投影的角度以及各个角的坐标就可以将失真的图像还原出来,这就是透视变换的基本原理;
在该变换中适用的基本公式(变换过程)为:
得到最终结果为:
其中的 u,v 是原图像的坐标点, x,y 是变换后得到的图像坐标点
cv2.getPerspectiveTransform()
cv2.warpPerspective()
根据输入(原图像)和输出(变换后的图像)上的四对点坐标获得从原图到目标图像的透视变换矩阵
getPerspectiveTransform(src, dst, solveMethod=None)
此处参考:OpenCV-Python投影透视变换函数getPerspectiveTransform及warpPerspective详解
src:源图像上四个点的坐标构成的矩阵,要求其中任意三点不共线
dst:目标图像上四个点的坐标构成的矩阵,要求其中任意三个点不共线,且每个点与src的对应点对应
solveMethod:矩阵分解方法,传递给cv2.solve(DecompTypes) 求解线性方程组或解决最小二乘问题,默认值为None,表示使用DECOMP_LU
对输入图像进行透视变换
warpPerspective(src,M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)
src:输入图像矩阵
M:3*3的透视变换矩阵,可以通过getPerspectiveTransform等函数获取
dsize:结果图像大小,为宽和高的二元组
dst:输出结果图像,可以省略,结果图像会作为函数处理结果输出
flags:可选参数,插值方法的组合(int 类型)
borderMode:可选参数,边界像素模式(int 类型)
borderValue:可选参数,边界填充值
首先我们将一张正常的图像进行倾斜化:
"""
Author:XiaoMa
date:2021/10/21
"""
import cv2
import numpy as np
img = cv2.imread('E:\From Zhihu\For the desk\WZX.jpeg')
print(img.shape)
pts1 = np.float32([[0, 0], [500, 0], [0, 740], [500, 740]]) #获得原图坐标
pts2 = np.float32([[0, 100], [510, 0], [100, 760], [500, 740]]) #获得目标图坐标(与原图坐标对应起来)
M = cv2.getPerspectiveTransform(pts1, pts2)
dst = cv2.warpPerspective(img, M, (520, 760))
cv2.namedWindow("W0")
cv2.namedWindow("W1")
cv2.imshow("W0", img)
cv2.waitKey(delay = 0)
cv2.imshow("W1", dst)
cv2.waitKey(delay = 0)
pts1 = np.float32([[0, 0], [500, 0], [0, 740], [500, 740]]) #获得原图坐标
pts2 = np.float32([[0, 100], [510, 0], [100, 760], [500, 740]]) #获得目标图坐标(与原图坐标对应起来)
上面两句代码中的坐标一定要对应起来,进行坐标点的对应才能得到正确的透视矩阵
实现结果如下:
进行复原:
对于自己修改的图进行复原还是比较简单的:
"""
Author:XiaoMa
date:2021/10/21
"""
import cv2
import numpy as np
img = cv2.imread('E:\From Zhihu\For the desk\WZX.jpeg')
print(img.shape)
pts1 = np.float32([[0, 0], [500, 0], [0, 740], [500, 740]])
pts2 = np.float32([[0, 100], [510, 0], [100, 760], [500, 740]])
M = cv2.getPerspectiveTransform(pts1, pts2)
#将原图倾斜
dst = cv2.warpPerspective(img, M, (520, 760))
cv2.namedWindow("W0")
cv2.namedWindow("W1")
cv2.imshow("W0", img)
cv2.waitKey(delay = 0)
cv2.imshow("W1", dst)
cv2.waitKey(delay = 0)
#复原图像
pts3 = np.float32([[0, 0], [500, 0], [0, 740], [500, 740]])
M1 = cv2.getPerspectiveTransform(pts2, pts3)
dst1 = cv2.warpPerspective(img, M1, (500, 740))
cv2.namedWindow("W2")
cv2.imshow("W2", dst1)
cv2.waitKey(delay = 0)
王祖贤,永远的神!!!