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

相关推荐
孟健5 小时前
Karpathy 用 200 行纯 Python 从零实现 GPT:代码逐行解析
python
码路飞7 小时前
写了个 AI 聊天页面,被 5 种流式格式折腾了一整天 😭
javascript·python
曲幽9 小时前
FastAPI压力测试实战:Locust模拟真实用户并发及优化建议
python·fastapi·web·locust·asyncio·test·uvicorn·workers
敏编程14 小时前
一天一个Python库:jsonschema - JSON 数据验证利器
python
前端付豪14 小时前
LangChain记忆:通过Memory记住上次的对话细节
人工智能·python·langchain
databook14 小时前
ManimCE v0.20.1 发布:LaTeX 渲染修复与动画稳定性提升
python·动效
花酒锄作田1 天前
使用 pkgutil 实现动态插件系统
python
前端付豪1 天前
LangChain链 写一篇完美推文?用SequencialChain链接不同的组件
人工智能·python·langchain
曲幽1 天前
FastAPI实战:打造本地文生图接口,ollama+diffusers让AI绘画更听话
python·fastapi·web·cors·diffusers·lcm·ollama·dreamshaper8·txt2img
老赵全栈实战1 天前
Pydantic配置管理最佳实践(一)
python