python学opencv|读取图像(三十二)使用cv2.getPerspectiveTransform()函数制作透视图-变形的喵喵

【1】引言

前序已经对图像展开了平移、旋转缩放和倾斜拉伸技巧探索,相关链接为:

python学opencv|读取图像(二十八)使用cv2.warpAffine()函数平移图像-CSDN博客

python学opencv|读取图像(二十九)使用cv2.getRotationMatrix2D()函数旋转缩放图像-CSDN博客

python学opencv|读取图像(三十)使用cv2.getAffineTransform()函数倾斜拉伸图像-CSDN博客

在此基础上我们更进一步,制作透视图,将使用cv2.getPerspectiveTransform()函数。

实际上,cv2.getPerspectiveTransform()函数的执行,相对于实现倾斜拉伸效果的cv2.getAffineTransform()函数,是一个扩维操作,把控制三个点转化为控制四个点。

倾斜拉伸效果控制三个点,图像的两个对边保持互相平行;透视效果控制四个点,图像的各个边将不再保持平行。

如果把实现倾斜拉伸效果称做仿射变换,把实现透视效果称做透视变换,有如下的对比效果:

++图1++

【2】官网教程

要想图像实现透视,需要调用cv2.getPerspectiveTransform()函数。点击下述链接,直达该函数的官网说明:

OpenCV: Geometric Image Transformations

在官网,我们看到cv2.getPerspectiveTransform()函数本身也只需要两个点集做参数:

++图2++

这里的参数意义是:

Mat cv::getPerspectiveTransform ( const Point2f src[], #原始图点集

const Point2f dst[], #透视图点集

int solveMethod = DECOMP_LU ) #矩阵转换方法,不是重点,暂不讨论

【3】代码测试

这里直接给出完整代码:

python 复制代码
import cv2 as cv # 引入CV模块
import numpy as np #引入numpy模块

# 读取图片
src = cv.imread('srcm.png')

#设置点
rows=len(src) #读取图像行数
cols=len(src[0]) #读取图像列数
p1=np.zeros((4,2),np.float32) #32位浮点型全0矩阵
p1[0]=[0,0] #第一点
p1[1]=[cols-1,0] #第二点
p1[2]=[0,rows-1] #第三点
p1[3]=[cols-1,rows-1] #第四点
p2=np.zeros((4,2),np.float32) #32位浮点型全0矩阵
p2[0]=[90,0] #新的第一点
p2[1]=[(cols-90),0] #新的第二点
p2[2]=[0,1*(rows-1)] #新的第三点
p2[3]=[cols-1,1*(rows-1)] #新的第四点
#center=(rows/2,cols/2) #旋转中心
#M=np.float32([[1,0,50],
              #[0,1,200]]) #M矩阵,x=50,y=200
M=cv.getPerspectiveTransform(p1,p2)
#M=cv.getAffineTransform(p1,p2)
#M=cv.getRotationMatrix2D(center,60,0.8) #旋转并缩放图像
dst=cv.warpPerspective(src,M,(cols,rows))#输出图像
#dst=cv.warpAffine(src,M,(cols,rows)) #输出图像
cv.imshow('srcm-qxls', dst)  # 在屏幕展示绘制圆形的效果
cv.imwrite('srcm-ts.png', dst)  # 保存图像
cv.waitKey()  # 图像不会自动关闭
cv.destroyAllWindows()  # 释放所有窗口

需要注意的是,这里控制四个点的设置方法:

复制代码
p1=np.zeros((4,2),np.float32) #32位浮点型全0矩阵
p1[0]=[0,0] #第一点
p1[1]=[cols-1,0] #第二点
p1[2]=[0,rows-1] #第三点
p1[3]=[cols-1,rows-1] #第四点
p2=np.zeros((4,2),np.float32) #32位浮点型全0矩阵
p2[0]=[90,0] #新的第一点
p2[1]=[(cols-90),0] #新的第二点
p2[2]=[0,1*(rows-1)] #新的第三点
p2[3]=[cols-1,1*(rows-1)] #新的第四点

在cv2.getPerspectiveTransform()函数中,新旧的第一第二第三和第四点互相替换,实现透视变化。

原始图像为:

++图3++

新的图像为:

++图4++

需要注意的是,此时的输出图像使用的是cv2.warpPerspective()函数,该函数和之前的cv2.warpAffine()函数用法几乎完全一致。

【4】透视探索

控制四个点比控制三个点要灵活得多,所以,也有可能实现对边平行,如果按照下述方式设置新旧点,就会出现平行边:

复制代码
p1=np.zeros((4,2),np.float32) #32位浮点型全0矩阵
p1[0]=[0,0] #第一点
p1[1]=[cols-1,0] #第二点
p1[2]=[0,rows-1] #第三点
p1[3]=[cols-1,(rows-1)] #第四点
p2=np.zeros((4,2),np.float32) #32位浮点型全0矩阵
p2[0]=[cols-1,0.5*(rows-1)] #新的第一点
p2[1]=[0.5*(cols-1),0] #新的第二点
p2[2]=[0.5*(cols-1),rows-1] #新的第三点
p2[3]=[0,0.5*(rows-1)] #新的第四点

或者按照下述方式:

复制代码
p1=np.zeros((4,2),np.float32) #32位浮点型全0矩阵
p1[0]=[0,0] #第一点
p1[1]=[cols-1,0] #第二点
p1[2]=[0,rows-1] #第三点
p1[3]=[cols-1,(rows-1)] #第四点
p2=np.zeros((4,2),np.float32) #32位浮点型全0矩阵
p2[0]=[0.5*(cols-1),0] #新的第一点
p2[1]=[cols-1,0.5*(rows-1)] #新的第二点
p2[2]=[0,0.5*(rows-1)] #新的第三点
p2[3]=[0.5*(cols-1),rows-1] #新的第四点

对边平行的透视效果为:

++图5++

如果仔细对比会发现,在实现上述对边平行的透视效果过程中,新旧点并没有按照严格的一二三四对应排列。

如果严格按照一二三四的顺序排列:

复制代码
p1=np.zeros((4,2),np.float32) #32位浮点型全0矩阵
p1[0]=[0,0] #第一点
p1[1]=[cols-1,0] #第二点
p1[2]=[0,rows-1] #第三点
p1[3]=[cols-1,(rows-1)] #第四点
p2=np.zeros((4,2),np.float32) #32位浮点型全0矩阵
p2[0]=[0.5*(cols-1),0] #新的第一点
p2[1]=[cols-1,0.5*(rows-1)] #新的第二点
p2[2]=[0.5*(cols-1),rows-1] #新的第三点
p2[3]=[0,0.5*(rows-1)] #新的第四点
复制代码
获得的透视图为:

++图6++

由图6可见,图像出现了预想不到的拼接。

【5】总结

掌握了使用python+opencv实现图像透视变化的技巧。

相关推荐
liuyunshengsir2 分钟前
PyTorch 动态量化(Dynamic Quantization)
人工智能·pytorch·python
电子云与长程纠缠10 分钟前
UE5制作六边形包裹球体效果
开发语言·python·ue5
DFT计算杂谈19 分钟前
KPROJ编译教程
java·前端·python·算法·conda
念恒123061 小时前
Python(循环中断)
开发语言·python
tsfy20031 小时前
Python 处理中文文件名的3个坑(附 Flask 上传解决函数)
开发语言·python·flask·文件上传·中文编码
AI技术控1 小时前
KV Cache 缓存机制的原理和应用:从 Transformer 推理到大模型服务优化
人工智能·python·深度学习·缓存·自然语言处理·transformer
vx-程序开发2 小时前
基于机器学习的动漫可视化系统的设计与实现-计算机毕业设计源码08339
java·c++·spring boot·python·spring·django·php
gihigo19982 小时前
基于粒子滤波的三维雷达目标跟踪方案
人工智能·计算机视觉·目标跟踪
J&A~ing2 小时前
第一章 opencv 的 Windows源码在 Visual Studio 下的编译安装
人工智能·windows·opencv·计算机视觉·visual studio
爱睡懒觉的焦糖玛奇朵2 小时前
【从视频到数据集:焦糖玛奇朵的魔法工具Video To YOLO Dataset】
人工智能·python·学习·yolo·音视频