【版权声明】
本文为博主原创文章,未经博主允许严禁转载,我们会定期进行侵权检索。
cv2.warpPerspective函数是OpenCV库中用于执行透视变换的函数之一。它可以将图像从一个透视投影转换为另一个透视投影,实现图像的旋转、缩放、平移等操作。该操作可表示为:
DST = M * SRC
上式中SRC表示原图像,DST表示变换后图像,M表示透视变换矩阵(3x3)。
1 cv2.warpPerspective
cv2.warpPerspective函数在OpenCV中用于执行透视变换,其计算过程和各个参数如下所示:
1.1 计算过程
(1)定义目标图像的大小和数据类型(dtype)。
(2)计算透视变换矩阵(3x3矩阵),可以通过cv2.getPerspectiveTransform函数获得。
(3)应用透视变换矩阵到源图像上的每个像素,计算其在目标图像中的位置。
(4)根据这个位置,使用插值方法估算目标图像中的像素值。
在第三步中,其实现方式实际是依据M’ * DST = SRC,即根据目标尺寸计算其在源图中对应位置,然后获取原图相应位置的像素值。这里M’表示M的逆矩阵。
1.2 参数说明
src: 源图像,即待进行透视变换的图像。
M: 变换矩阵,即3x3的透视变换矩阵。
dsize: 目标图像的大小,以元组形式表示,例如(width, height)。
flags: 插值方法的标志,用于指定插值方法,默认为cv2.INTER_LINEAR。
borderMode: 边界模式,用于指定超出边界的像素处理方式,默认为cv2.BORDER_CONSTANT。
borderValue: 当边界模式为cv2.BORDER_CONSTANT时,用于指定边界像素的值,默认为0。
1.3 返回值
dst: 目标图像,即经过透视变换后的图像。
2 示例程序
示例程序如下所示。
import cv2
import numpy as np
if __name__ == '__main__':
# 生成输入图像
h, w = 200, 300 # 图像大小
origin_image = np.zeros((h, w), dtype=np.uint8)
pts = np.array([[50, 50], [100, 160], [250, 100]], np.int32)
pts = pts.reshape((-1, 1, 2))
origin_image = cv2.fillConvexPoly(origin_image, pts, 255, 100)
# 透视变换矩阵
M = np.array([[0.99, -0.11, 80], [-0.11, 0.99, 30], [0, 0, 1]])
# opencv透视变换
dst_opencv = cv2.warpPerspective(origin_image.copy(), M, (w, h))
# 显示原始图像和经过透视变换后的图像
cv2.imshow('original', origin_image)
cv2.imshow('opencv', dst_opencv)
cv2.waitKey(0)
cv2.destroyAllWindows()
示例程序的原始图像和变换后图像如下所示。
3 自定义验证程序mdst
基于公式验证M’ * DST = SRC变换过程,程序如下所示。
import cv2
import numpy as np
# warp_perspective验证,M' * DST = SRC
def m_dst(src, M, dsize):
M = np.linalg.inv(M) # 求逆矩阵
dst = np.zeros((dsize[1], dsize[0]), dtype=np.uint8)
pos = np.array(np.meshgrid(range(dsize[0]), range(dsize[1]))).T.reshape(-1, 2)
dpos = np.hstack((pos, np.ones((pos.shape[0], 1)))).T
spos = M @ dpos
spos = spos / spos[2, :]
spos = spos.astype(np.int64).T[:, :2]
mask = np.where((spos[:, 0] < dsize[0]) & (spos[:, 0] >= 0) & (spos[:, 1] < dsize[1]) & (spos[:, 1] >= 0))
spos = spos[mask]
dpos = pos[mask]
dst[dpos[:, 1], dpos[:, 0]] = src[spos[:, 1], spos[:, 0]]
return dst
if __name__ == '__main__':
# 生成输入图像
h, w = 200, 300 # 图像大小
origin_image = np.zeros((h, w), dtype=np.uint8)
pts = np.array([[50, 50], [100, 160], [250, 100]], np.int32)
pts = pts.reshape((-1, 1, 2))
origin_image = cv2.fillConvexPoly(origin_image, pts, 255, 100)
# 透视变换矩阵
M = np.array([[0.99, -0.11, 80], [-0.11, 0.99, 30], [0, 0, 1]])
# M' * DST = SRC
dst_mdst = m_dst(origin_image, M, (w, h))
# 显示原始图像和经过透视变换后的图像
cv2.imshow('original', origin_image)
cv2.imshow('mdst', dst_mdst)
cv2.waitKey(0)
cv2.destroyAllWindows()
原始图像和变换后图像如下所示。
4 自定义验证程序msrc
基于公式验证DST = M * SRC变换过程,程序如下所示。
import cv2
import numpy as np
# warp_perspective验证,DST = M * SRC
def m_src(src, M, dsize):
dst = np.zeros((dsize[1], dsize[0]), np.uint8)
pos = np.where(src > 0)
pos = np.vstack((pos[1], pos[0], np.ones_like(pos[0])))
pos = M @ pos
pos = pos / pos[2, :]
pos = pos.astype(np.int64).T[:, :2]
pos = pos[np.where((pos[:, 0]<dsize[0]) & (pos[:, 0]>=0) & (pos[:, 1]<dsize[1]) & (pos[:, 1]>=0))]
dst[pos[:, 1], pos[:, 0]] = 255
return dst
if __name__ == '__main__':
# 生成输入图像
h, w = 200, 300 # 图像大小
origin_image = np.zeros((h, w), dtype=np.uint8)
pts = np.array([[50, 50], [100, 160], [250, 100]], np.int32)
pts = pts.reshape((-1, 1, 2))
origin_image = cv2.fillConvexPoly(origin_image, pts, 255, 100)
# 透视变换矩阵
M = np.array([[0.99, -0.11, 80], [-0.11, 0.99, 30], [0, 0, 1]])
# M' * DST = SRC
dst_msrc = m_src(origin_image, M, (w, h))
# 显示原始图像和经过透视变换后的图像
cv2.imshow('original', origin_image)
cv2.imshow('msrc', dst_msrc)
cv2.waitKey(0)
cv2.destroyAllWindows()
原始图像和变换后图像如下所示。
5 注意事项
(1)自定义验证程序mdst和msrc未进行插值,仅仅实现了透视变换过程,可以明显看到边缘效果不如opencv版本。
(2)mdst和msrc正常情况下结果趋向阈值,但是由于程序中存在一个取整的近似操作,所以二者所得结果不完全相同。在部分情况下,msrc经变换后会出现大量重叠,分辨率下降,效果差于mdst方法。
【版权声明】
本文为博主原创文章,未经博主允许严禁转载,我们会定期进行侵权检索。 文章来源:https://www.toymoban.com/news/detail-845643.html
更多python与C++技巧、三维算法、深度学习算法总结、大模型请关注我的博客,欢迎讨论与交流:https://blog.csdn.net/suiyingy,或”乐乐感知学堂“公众号。Python三维领域专业书籍推荐:《人工智能点云处理及深度学习算法》。文章来源地址https://www.toymoban.com/news/detail-845643.html
到了这里,关于opencv warpPerspective透视变换实现原理与过程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!