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

相关推荐
怒放吧德德1 小时前
Python3基础:基础实战巩固,从“会用”到“活用”
后端·python
aiguangyuan1 小时前
基于BERT的中文命名实体识别实战解析
人工智能·python·nlp
喵手1 小时前
Python爬虫实战:知识挖掘机 - 知乎问答与专栏文章的深度分页采集系统(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·采集知乎问答与专栏文章·采集知乎数据·采集知乎数据存储sqlite
铉铉这波能秀1 小时前
LeetCode Hot100数据结构背景知识之元组(Tuple)Python2026新版
数据结构·python·算法·leetcode·元组·tuple
kali-Myon1 小时前
2025春秋杯网络安全联赛冬季赛-day2
python·安全·web安全·ai·php·pwn·ctf
Dfreedom.2 小时前
图像处理中的对比度增强与锐化
图像处理·人工智能·opencv·锐化·对比度增强
Olamyh2 小时前
【 超越 ReAct:手搓 Plan-and-Execute (Planner) Agent】
python·ai
deepxuan2 小时前
Day7--python
开发语言·python
曲幽2 小时前
FastAPI不止于API:手把手教你用Jinja2打造动态Web页面
python·fastapi·backend·jinja2·full stack·template engine·web development
禹凕2 小时前
Python编程——进阶知识(多线程)
开发语言·爬虫·python