opencv-24 图像几何变换03-仿射-cv2.warpAffine()

什么是仿射?

仿射变换是指图像可以通过一系列的几何变换来实现平移、旋转等多种操作。该变换能够
保持图像的平直性和平行性。平直性是指图像经过仿射变换后,直线仍然是直线;平行性是指 图像在完成仿射变换后,平行线仍然是平行线。

OpenCV 中的仿射函数为 cv2.warpAffine(),其通过一个变换矩阵(映射矩阵)M 实现变换,
具体为:
dst(𝑥, 𝑦) = src(𝑀11𝑥 + 𝑀12𝑦 + 𝑀13, 𝑀21𝑥 + 𝑀22𝑦 + 𝑀23)
如图 5-2 所示,可以通过一个变换矩阵 M,将原始图像 O 变换为仿射图像 R

在这里插入图片描述
因此,可以采用仿射函数 cv2.warpAffine()实现对图像的旋转,该函数的语法格式如下:

dst = cv2.warpAffine( src, M, dsize[, flags[, borderMode[, borderValue]]] )

式中:
dst 代表仿射后的输出图像,该图像的类型和原始图像的类型相同。

dsize 决定输出图像的实际大小。

src 代表要仿射的原始图像。

M 代表一个 2×3 的变换矩阵。使用不同的变换矩阵,就可以实现不同的仿射变换。

dsize 代表输出图像的尺寸大小。

flags 代表插值方法,默认为 INTER_LINEAR。当该值为 WARP_INVERSE_MAP 时,
意味着 M 是逆变换类型,实现从目标图像 dst 到原始图像 src 的逆变换。
 borderMode 代表边类型, 默认为 BORDER_CONSTANT 。 当 该值为 BORDER_TRANSPARENT 时,意味着目标图像内的值不做改变,这些值对应原始图像内的异常
值。
 borderValue 代表边界值,默认是 0。
通过以上分析可知,在 OpenCV 中使用函数 cv2.warpAffine()实现仿射变换,忽略其可选参数后的语法格式为:

dst = cv2.warpAffine( src , M , dsize )

其通过转换矩阵 M 将原始图像 src 转换为目标图像 dst:

dst(𝑥, 𝑦) = src(𝑀11𝑥 + 𝑀12𝑦 + 𝑀13, 𝑀21𝑥 + 𝑀22𝑦 + 𝑀23)

因此,进行何种形式的仿射变换完全取决于转换矩阵 M。下面分别介绍通过不同的转换矩阵 M 实现的不同的仿射变换。

平移

通过转换矩阵 M 实现将原始图像 src 转换为目标图像 dst:
dst(𝑥, 𝑦) = src(𝑀11𝑥 + 𝑀12𝑦 + 𝑀13, 𝑀21𝑥 + 𝑀22𝑦 + 𝑀23)
将原始图像 src 向右侧移动 100 个像素、向下方移动 200 个像素,则其对应关系为:
dst (x, y) = src (x + 100, y + 200)
将上述表达式补充完整,即:
dst (x, y) = src (1·x + 0·y + 100, 0·x + 1·y + 200)
根据上述表达式,可以确定对应的转换矩阵 M 中各个元素的值为:
 M11=1
 M12=0
 M13=100
 M21=0
 M22=1
 M23=200
将上述值代入转换矩阵 M,得到:

在这里插入图片描述
在已知转换矩阵 M 的情况下,可以直接利用转换矩阵 M 调用函数 cv2.warpAffine() 完成图像的平移。

实验:利用自定义转换矩阵完成图像平移。

import cv2
import numpy as np
img=cv2.imread("lena.png")
height,width=img.shape[:2]
x=100
y=200
M = np.float32([[1, 0, x], [0, 1, y]])
move=cv2.warpAffine(img,M,(width,height))
cv2.imshow("original",img)
cv2.imshow("move",move)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:
在这里插入图片描述
其中左图是原始图像,右图是移动结果图像

旋转

在使用函数 cv2.warpAffine()对图像进行旋转时,可以通过函数 cv2.getRotationMatrix2D()
获取转换矩阵。该函数的语法格式为:

retval=cv2.getRotationMatrix2D(center, angle, scale)

式中:
 center 为旋转的中心点。
 angle 为旋转角度,正数表示逆时针旋转,负数表示顺时针旋转。
 scale 为变换尺度(缩放大小)。

利用函数 cv2.getRotationMatrix2D()可以直接生成要使用的转换矩阵 M。

例如,想要以图像中心为圆点,逆时针旋转 45°,并将目标图像缩小为原始图像的 0.6 倍,则在调用函数
cv2.getRotationMatrix2D()生成转换矩阵 M 时所使用的语句为:

M=cv2.getRotationMatrix2D((height/2,width/2),45,0.6)

实验2:完成图像旋转

代码:

import cv2
import numpy as np
img=cv2.imread("lena.png")
height,width=img.shape[:2]
M=cv2.getRotationMatrix2D((width/2,height/2),45,0.6)
rotate=cv2.warpAffine(img,M,(width,height))
cv2.imshow("original",img)
cv2.imshow("rotation",rotate)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述
其中左图是原始图像,右图是旋转结果图像

更复杂的仿射变换

对于更复杂仿射变换,OpenCV 提供了
函数 cv2.getAffineTransform()来生成仿射函数 cv2.warpAffine()所使用的转换矩阵 M。该函数的语法格式为:

retval=cv2.getAffineTransform(src, dst)

式中:
 src 代表输入图像的三个点坐标。
 dst 代表输出图像的三个点坐标。
在该函数中,其参数值 src 和 dst 是包含三个二维数组(x, y)点的数组。上述参数通过函数
cv2.getAffineTransform()定义了两个平行四边形。src 和 dst 中的三个点分别对应平行四边形的
左上角、右上角、左下角三个点。函数 cv2.warpAffine()以函数 cv2.getAffineTransform()获取的
转换矩阵 M 为参数,将 src 中的点仿射到 dst 中。函数 cv2.getAffineTransform()
对所指定的点完成映射后,将所有其他点的映射关系按照指定点的关系计算确定。

实验3:完成图像仿射

import cv2
import numpy as np
img=cv2.imread('lena.png')
rows,cols,ch=img.shape
#定义三个点
p1=np.float32([[0,0],[cols-1,0],[0,rows-1]])print(p1)
#定义三个点的变换位置
p2=np.float32([[0,rows*0.33],[cols*0.85,rows*0.25],[cols*0.15,rows*0.7]])
print(p2)
#生成变换矩阵
M=cv2.getAffineTransform(p1,p2)
#进行仿射变换
dst=cv2.warpAffine(img,M,(cols,rows))
cv2.imshow("origianl",img)
cv2.imshow("result",dst)
cv2.waitKey()
cv2.destroyAllWindows()

首先构造了两个三分量的点集合 p1 和 p2,分别用来指代原始图像和目标图像内平行四边形的三个顶点(左上角、右上角、左下角)。
然后使用
M=cv2.getAffineTransform(p1,p2)
获取转换矩阵 M。接下来,
dst=cv2.warpAffine(img,M,(cols,rows))
完成了从原始图像到目标图像的仿射。

运行结果:

其中左图是原始图像,右图是仿射结果图像

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/9432.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于LNMP配置WordPress建站时出现的问题汇总

这里写目录标题 wordpress上传文件报错问题描述原因分析:解决方案: wordpress裁剪图片报错问题描述原因分析:解决方案: wordpress上传文件报错 WP内部错误,在上传文件时发生了错误,显示权限不足无法保存 …

SQL注入--题目

联合查询注入: bugku-这是一个神奇的登录框 手工注入: 点吧,输入0’发现还是: 输入0" 发现报错: 确定可以注入,判断字段有多少个 0"order by 1,2,3# 发现: 说明有两列。 输入 0&qu…

Docker系列---【docker和docker容器设置开机启动】

docker和docker容器设置开机启动 1、设置docker开机启动 systemctl enable docker 2、设置容器自动重启 1)创建容器时设置 docker run -d --restartalways --name 设置容器名 使用的镜像 (上面命令 --name后面两个参数根据实际情况自行修改)# Docker 容器的重启策略如下&#…

【论文阅读22】Label prompt for multi-label text classification

论文相关 论文标题:Label prompt for multi-label text classification(基于提示学习的多标签文本分类) 发表时间:2023 领域:多标签文本分类 发表期刊:Applied Intelligence(SCI二区&#xff0…

Linux 常用命令全拼

pwd:print work directoryps:process statusdf:disk freedu:disk usagecat:concatenate 连锁,连接insmod:install module 载入模块ln -s:link -soft 创建一个软链接,相当…

9 Linux实操篇-实用指令

9 Linux实操篇-实用指令 文章目录 9 Linux实操篇-实用指令9.1 指定和修改运行级别-init/systemctl9.2 找回root密码9.3 Linux的指令说明9.3 帮助类-man/help9.4 文件目录类-pwd/ls/cd/mkdir/...9.5 时间日期类-date/cal9.6 搜索查找类-find/locate/which/grep9.7 压缩和解压类-…

SpringBoot整合Elasticsearch

SpringBoot整合Elasticsearch SpringBoot整合Elasticsearch有以下几种方式: 使用官方的Elasticsearch Java客户端进行集成 通过添加Elasticsearch Java客户端的依赖,可以直接在Spring Boot应用中使用原生的Elasticsearch API进行操作。参考文档 使用Sp…

【Leetcode】50. Pow(x, n)

一、题目 1、题目描述 实现 pow(x, n) ,即计算 x 的整数 n 次幂函数(即, x n x^n xn )。 示例1: 输入:x 

数据库中的事务处理

MySQL的事务处理:只支持 lnnoDB 和BDB数据表类型 1.事务就是将一组SQL语句放在同一批次内去执行 2.如果一个SQL语句出错,则该批次内的所有SQL都将被取消执行 MySQL的事务实现方法一: select autocommit 查询当前事务提交模式 set a…

浅析交互中事实与价值信息的坍缩

在人机交互中,事实与价值的坍缩过程指的是在人与机器智能进行交互时,由于机器智能的回答和信息输出受到编程算法和数据训练的限制,导致人们难以准确区分机器智能提供的信息是基于客观事实还是主观价值观。 以下是人机交互中可能发生的事实与价…

机器学习深度学习——图像分类数据集

👨‍🎓作者简介:一位即将上大四,正专攻机器学习的保研er 🌌上期文章:机器学习&&深度学习——softmax回归(下) 📚订阅专栏:机器学习&&深度学习…

JavaScript与TypeScript的区别

JavaScript和TypeScript是两种不同的编程语言,在一些方面有一些区别。 1. 类型系统:JavaScript是一种动态类型语言,变量的类型是在运行时确定的,并且可以随时更改。而TypeScript引入了静态类型系统,可以在编译时检查代…

PHP在线相册--【强撸项目】

强撸项目系列总目录在000集 PHP要怎么学–【思维导图知识范围】 文章目录 本系列校训本项目使用技术 上效果图phpStudy 设置导数据库项目目录如图:代码部分:主页 配套资源作业: 本系列校训 用免费公开视频,卷飞培训班哈人&…

【Matlab】基于粒子群优化算法优化BP神经网络的数据回归预测(Excel可直接替换数据)

【Matlab】基于粒子群优化算法优化 BP 神经网络的数据回归预测(Excel可直接替换数据) 1.模型原理2.数学公式3.文件结构4.Excel数据5.分块代码5.1 fun.m5.2 main.m 6.完整代码6.1 fun.m6.2 main.m 7.运行结果 1.模型原理 基于粒子群优化算法(…

国标GB28181协议视频平台EasyCVR修改录像计划等待时间较长的原因排查与解决

音视频流媒体视频平台EasyCVR拓展性强,视频能力丰富,具体可实现视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、H.265自动转码H.264、平台级联等。为了便于用户二次开发、调用与集成&…

MTK系统启动流程

MTK系统启动流程 boot rom -> preloader ->lk ->kernel ->Native -> Android 1、Boot rom:系统开机,最先执行的是固化在芯片内部的bootrom,其作用主要有 a.初始化ISRAM和EMMC b.当系统全擦后 ,也会配置USB,用来仿…

Caddy 中实现自动 HTTPS

要在 Caddy 中实现自动 HTTPS,您可以按照以下步骤进行操作: 步骤 1:安装 Caddy 首先,您需要安装 Caddy 服务器。您可以从 Caddy 的官方网站(https://caddyserver.com/)下载适用于您的操作系统的最新版本。…

CSS 瀑布流效果效果

示例 <!DOCTYPE html> <html lang="cn"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>瀑布流效果</title><style>…

IMU和视觉融合学习笔记

利用纯视觉信息进行位姿估计&#xff0c;对运动物体、光照干扰、场景纹理缺失等情况&#xff0c;定位效果不够鲁棒。当下&#xff0c;视觉与IMU融合(VI-SLAM&#xff09;逐渐成为常见的多传感器融合方式。视觉信息与IMU 数据进行融合&#xff0c;根据融合方式同样可分为基于滤波…

Java 文件过滤器 | 按条件筛选文件

文章目录 一、概述1.1 何时会用到文件过滤器1.2 工作流程1.3 常用的接口和类1.4 文件过滤器的作用 二、按文件属性过滤2.1 按前缀或后缀过滤文件名2.2 按文件大小过滤 三、按文件内容过滤3.1 文本文件过滤器3.1.1 根据关键字过滤文件内容3.1.2 使用正则表达式过滤文件内容 3.2 …