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

devtools/2025/1/13 3:37:36/

【1】引言

前序已经学习了如何平移和旋转缩放图像,相关文章链接为:

pythonopencv|读取图像(二十七)使用cv2.warpAffine()函数平移图像-CSDN博客

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

在此基础上,我们尝试倾斜拉伸图

【2】核心代码

前序学习进程中,已经知晓平移图像的核心代码是设置M矩阵,使其按照两行三列的形式,通过改变第三列的值来移动图像:

    此时的M矩阵有两个可选变量x和y:

    M=[[1,0,x],

          [0,1,y]],

    当x>0,图像向右移动x大小的位置;当y>0,图像向右下移动y大小的位置;当x和y取负值时图像分别向左和向上运动。

当我们想旋转图像时,需要调用一个cv2.getRotationMatrix2D()函数来实现旋转,通过定义旋转中心,旋转角度和缩放倍数实现旋转和缩放目标。

Mat cv::getRotationMatrix2D     (     Point2f     center, #旋转中心,需要提前定义好
        double     angle, #旋转角度
        double     scale ) #缩放倍数

而当我们想倾斜拉伸图像时,是根据图像的坐标点来操作的:

输入图像有四个顶角;

取三个顶角的点坐标即可知晓图像大小;

给出新的三个坐标点,替换之前取到的三个坐标点,即可倾斜拉伸图像。

具体调用的函数为:cv2.getAffineTransform(p1,p2)。

点击下述链接,直达函数官网教程:

OpenCV: Geometric Image Transformations

在这里会看到对函数的详细介绍,非常简单,函数里练得输入是两个集合,每个集合由三个坐标点组成。

【3】代码测试

首先是引入模块和完成初始图像的读取:

python">import cv2 as cv # 引入CV模块
import numpy as np #引入numpy模块# 读取图片
src = cv.imread('srcm.png')

然后先读取原图想的三个点:

python">#设置点
rows=len(src) #读取图像行数
cols=len(src[0]) #读取图像列数
p1=np.zeros((3,2),np.float32) #32位浮点型全0矩阵
p1[0]=[0,0] #第一点
p1[1]=[cols-1,0] #第二点
p1[2]=[0,rows-1] #第三点

再设置新的三个点:

python">p2=np.zeros((3,2),np.float32) #32位浮点型全0矩阵
p2[0]=[100,0] #新的第一点
p2[1]=[cols-1,0] #新的第二点
p2[2]=[0,rows-1] #新的第三点

之后通过调用cv2.getAffineTransform(p1,p2)函数,用p2的三个点坐标替换p1的三个点坐标,由此实现图像的倾斜拉伸:

python">cv.getAffineTransform(p1,p2)

 最后回到cv2.warpAffine()函数实现图像的输出、显示和保存:

python">dst=cv.warpAffine(src,M,(cols,rows)) #输出图像
cv.imshow('srcm-qxls', dst)  # 在屏幕展示绘制圆形的效果
cv.imwrite('srcm-qxls.png', dst)  # 保存图像
cv.waitKey()  # 图像不会自动关闭
cv.destroyAllWindows()  # 释放所有窗口

使用的初始图像为:srcm.png

图1 srcm.png

代码运行后的输出图像为:

图2 srcm-qxls.png

【4】细节说明

这里给出的两组点,其实p1[1]=p2[1],p1[2]=p2[2];发生变化的是p1[0]到p2[0]:也就是把左上角的顶点往右移动100个像素位置,此时图像会自动保持侧面的边线平行,让右下角的点左移100个像素点。这就是图2所示的模样。

p1=np.zeros((3,2),np.float32) #32位浮点型全0矩阵
p1[0]=[0,0] #第一点
p1[1]=[cols-1,0] #第二点
p1[2]=[0,rows-1] #第三点p2=np.zeros((3,2),np.float32) #32位浮点型全0矩阵
p2[0]=[100,0] #新的第一点
p2[1]=[cols-1,0] #新的第二点
p2[2]=[0,rows-1] #新的第三点

【5】总结

掌握了python+opencv实现图像倾斜拉伸的技巧。


http://www.ppmy.cn/devtools/150044.html

相关文章

STM32内置Flash

一、原理 利用flash存储用户数据需要注意查看,用户数据是否会覆盖芯片运行程序。 IAP(在程序中编程)利用程序修改程序本身,和OTA是一个原理。IAP在程序中编程支持任意一种通信下载。 ICP(在电路中编程,通…

漫谈网络安全策略

1.引言 随着计算机网络的不断发展,全球信息化已成为人类发展的大趋势。但由于计算机网络具有联结形式多样性、终端分布不均匀性和网络的开放性、互连性等特征,致使网络易受黑客、怪客、恶意软件和其他不轨的攻击,所以网上信息的安全和保密是一…

统计模型的Flops和Params

1、方法一 thop from thop import profile, clever_format model Model() ## 实例化模型input torch.randn(1, 3, 128, 128) ## 模拟输入flops, params profile(model, inputs(input,)) flops, params clever_format([flops, params], "%.3f") print(flops: {…

【gRPC】header和trailer两种元数据机制go案例

gRPC Header 和 Trailer gRPC 提供了 Header 和 Trailer 两种元数据机制,用于在客户端和服务端之间传递附加信息。 Header 和 Trailer 的区别 元数据类型发送时机常见用途HeaderRPC 调用开始时,随响应发送包含认证信息、会话数据、请求相关的元信息&a…

体育实时数据是怎么获取的

体育实时数据的获取通常依赖于技术、数据提供商以及基础设施的综合应用。以下是主要的获取方式和技术手段: 1. 官方渠道数据接口 体育联赛与赛事方的API:一些官方机构(如FIFA、NBA、MLB等)提供实时数据接口,这些接口…

汽车物资拍卖系统架构与功能分析

2015工作至今,10年资深全栈工程师,CTO,擅长带团队、攻克各种技术难题、研发各类软件产品,我的代码态度:代码虐我千百遍,我待代码如初恋,我的工作态度:极致,责任&#xff…

Spring实现通过工具类统一输出日志(不改变日志类信息)

版权说明: 本文由CSDN博主keep丶原创,转载请保留此块内容在文首。 原文地址: https://blog.csdn.net/qq_38688267/article/details/145022997 背景 实现输出带动态标签的日志需求后,实际操作过程中,输出日志的代码为&a…

【线性代数】通俗理解特征向量与特征值

这一块在线性代数中属于重点且较难理解的内容,下面仅个人学习过程中的体会,错误之处欢迎指出,有更简洁易懂的理解方式也欢迎留言学习。 文章目录 概念计算几何直观理解意义PS.适用 概念 矩阵本身就是一个线性变换,对一个空间中的…