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实现图像透视变化的技巧。

相关推荐
叫我:松哥3 分钟前
基于Python的共享单车租赁数据分析与预测系统,技术栈flask+boostrap+随机森林+XGBoost
人工智能·python·深度学习·算法·随机森林·数据分析·flask
Li#12 分钟前
web端电商项目自动下单发货评价晒图需要用到的能力
python·自动化
雨辰AI32 分钟前
从零搭建大模型本地运行环境|Python+CUDA 基础配置避坑大全
大数据·开发语言·人工智能·python·ai·ai编程·ai写作
DogDaoDao42 分钟前
【第 05 篇】Python的字典与集合
开发语言·python·集合·字典
乐迪信息1 小时前
乐迪信息:港口船舶偏航难监管,AI智能监测实时发出预警提醒
大数据·人工智能·安全·计算机视觉·目标跟踪
ʜᴇɴʀʏ1 小时前
SSVOD 基础知识
人工智能·目标检测·计算机视觉
程序员爱德华1 小时前
计算机视觉-自动驾驶
机器学习·计算机视觉·自动驾驶
涛声依旧-底层原理研究所1 小时前
混合检索 + 重排:让 AI Agent 拥有「既全又准」的认知骨架
人工智能·python
努力写A题的小菜鸡1 小时前
01-PyTorch加载数据初认识(dataset运用)
人工智能·pytorch·python
abcy0712131 小时前
python fastapi celery hdfs 异步上传
python·hdfs·fastapi