Lesson3-1:OpenCV图像处理---几何变换

news2024/11/26 20:31:36

几何变换

学习目标

  • 掌握图像的缩放,平移,旋转等
  • 了解数字图像的仿射变换和透射变换

1 图像缩放

缩放是对图像的大小进行调整,即使图像放大或缩小。

  1. API
cv2.resize(src,dsize,fx=0,fy=0,interpolation=cv2.INTER_LINEAR)

参数:

  • src : 输入图像
  • dsize: 绝对尺寸,直接指定调整后图像的大小
  • fx,fy: 相对尺寸,将dsize设置为None,然后将fxfy设置为比例因子即可
  • interpolation:插值方法,
    在这里插入图片描述
  1. 示例
import cv2 as cv
# 1. 读取图片
img1 = cv.imread("./image/dog.jpeg")
# 2.图像缩放
# 2.1 绝对尺寸
rows,cols = img1.shape[:2]
res = cv.resize(img1,(2*cols,2*rows),interpolation=cv.INTER_CUBIC)

# 2.2 相对尺寸
res1 = cv.resize(img1,None,fx=0.5,fy=0.5)

# 3 图像显示
# 3.1 使用opencv显示图像(不推荐)
cv.imshow("orignal",img1)
cv.imshow("enlarge",res)
cv.imshow("shrink)",res1)
cv.waitKey(0)

# 3.2 使用matplotlib显示图像
fig,axes=plt.subplots(nrows=1,ncols=3,figsize=(10,8),dpi=100)
axes[0].imshow(res[:,:,::-1])
axes[0].set_title("绝对尺度(放大)")
axes[1].imshow(img1[:,:,::-1])
axes[1].set_title("原图")
axes[2].imshow(res1[:,:,::-1])
axes[2].set_title("相对尺度(缩小)")
plt.show()

在这里插入图片描述

2 图像平移

图像平移将图像按照指定方向和距离,移动到相应的位置。

  1. API
cv.warpAffine(img,M,dsize)

参数:

  • img: 输入图像
  • M 2 ∗ 3 2∗3 23移动矩阵
    对于(x,y)处的像素点,要把它移动到 ( x + t x , y + t y ) (x+t_{x},y+t_{y}) (x+tx,y+ty)处时, M M M矩阵应如下设置:
    M = [ 1 0 t x 0 1 t y ] M= \begin{bmatrix} %%不用输入对齐方式,默认是居中对齐 1&0&t_{x}\\ 0&1&t_{y}\\ && \end{bmatrix} M= 1001txty

注意:将 M M M设置为 n p . f l o a t 32 np.float32 np.float32类型的 N u m p y Numpy Numpy数组。

  • dsize: 输出图像的大小

注意:输出图像的大小,它应该是(宽度,高度)的形式。请记住, w i d t h width width=列数, h e i g h t height height=行数。

  • 示例

需求是将图像的像素点移动 ( 50 , 100 ) (50,100) (50,100)的距离:

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 1. 读取图像
img1 = cv.imread("./image/image2.jpg")

# 2. 图像平移
rows,cols = img1.shape[:2]
M = M = np.float32([[1,0,100],[0,1,50]])# 平移矩阵
dst = cv.warpAffine(img1,M,(cols,rows))

# 3. 图像显示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img1[:,:,::-1])
axes[0].set_title("原图")
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title("平移后结果")
plt.show()

在这里插入图片描述

3 图像旋转

图像旋转是指图像按照某个位置转动一定角度的过程,旋转中图像仍保持这原始尺寸。图像旋转后图像的水平对称轴、垂直对称轴及中心坐标原点都可能会发生变换,因此需要对图像旋转中的坐标进行相应转换。
那图像是怎么进行旋转的呢?如下图所示:
在这里插入图片描述
假设图像逆时针旋转 θ θ θ,则根据坐标转换可得旋转转换为:
{ x ′ = r c o s ( α − θ ) y ′ = r s i n ( α − θ ) \begin{cases} x^{'} =rcos(α - θ)\\ y^{'} = rsin(α - θ) \end{cases} {x=rcos(αθ)y=rsin(αθ)

其中:
r = x 2 + y 2 , s i n α y x 2 + y 2 , c o s α x x 2 + y 2 r=\sqrt{x^{2}+y^{2}} , sinα\frac{y}{\sqrt{x^{2}+y^{2}}},cosα\frac{x}{\sqrt{x^{2}+y^{2}}} r=x2+y2 ,sinαx2+y2 ycosαx2+y2 x
带入上面的公式中,有:
{ x ′ = x c o s θ + y s i n θ y ′ = − x s i n θ + y c o s θ \begin{cases} x^{'} = x cosθ+ysinθ \\ y^{'} = -x sinθ+ycosθ \end{cases} {x=xcosθ+ysinθy=xsinθ+ycosθ
也可以写成:
[ x ′ y ′ 1 ] = [ x y 1 ] [ c o s θ − s i n θ 0 s i n θ c o s θ 0 0 0 1 ] \begin{bmatrix} x^{'} & y^{'} & 1 \\ \end{bmatrix}= \begin{bmatrix} x & y & 1 \\ \end{bmatrix} \begin{bmatrix} cosθ& -sinθ &0 \\ sinθ & cosθ & 0\\ 0 & 0 & 1 \end{bmatrix} [xy1]=[xy1] cosθsinθ0sinθcosθ0001
同时我们要修正原点的位置,因为原图像中的坐标原点在图像的左上角,经过旋转后图像的大小会有所变化,原点也需要修正。

假设在旋转的时候是以旋转中心为坐标原点的,旋转结束后还需要将坐标原点移到图像左上角,也就是还要进行一次变换。
在这里插入图片描述
[ x ′ ′ y ′ ′ 1 ] = [ x ′ y ′ 1 ] [ 1 0 0 0 − 1 0 l e f t t o p 1 ] \begin{bmatrix} x^{''} & y^{''} & 1 \\ \end{bmatrix}= \begin{bmatrix} x^{'} & y^{'} & 1 \\ \end{bmatrix} \begin{bmatrix} 1& 0 &0 \\ 0 & -1 & 0\\ left & top & 1 \end{bmatrix} [x′′y′′1]=[xy1] 10left01top001
= [ x y 1 ] = [ c o s θ − s i n θ 0 s i n θ c o s θ 0 0 0 1 ] [ 1 0 0 0 − 1 0 l e f t t o p 1 ] = \begin{bmatrix} x & y& 1 \\ \end{bmatrix}= \begin{bmatrix} cosθ& -sinθ &0 \\ sinθ & cosθ & 0\\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1& 0 &0 \\ 0 & -1 & 0\\ left & top & 1 \end{bmatrix} =[xy1]= cosθsinθ0sinθcosθ0001 10left01top001

在OpenCV中图像旋转首先根据旋转角度和旋转中心获取旋转矩阵,然后根据旋转矩阵进行变换,即可实现任意角度和任意中心的旋转效果。

  1. API
cv2.getRotationMatrix2D(center, angle, scale)

参数:

  • center:旋转中心
  • angle:旋转角度
  • scale:缩放比例

返回:

  • M:旋转矩阵

调用cv.warpAffine完成图像的旋转

  1. 示例
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 1 读取图像
img = cv.imread("./image/image2.jpg")

# 2 图像旋转
rows,cols = img.shape[:2]
# 2.1 生成旋转矩阵
M = cv.getRotationMatrix2D((cols/2,rows/2),90,1)
# 2.2 进行旋转变换
dst = cv.warpAffine(img,M,(cols,rows))

# 3 图像展示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img1[:,:,::-1])
axes[0].set_title("原图")
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title("旋转后结果")
plt.show()

在这里插入图片描述

4 仿射变换

图像的仿射变换涉及到图像的形状位置角度的变化,是深度学习预处理中常到的功能,仿射变换主要是对图像的缩放,旋转,翻转和平移等操作的组合。

那什么是图像的仿射变换,如下图所示,图1中的点1, 2 和 3 与图二中三个点一一映射, 仍然形成三角形, 但形状已经大大改变,通过这样两组三点(感兴趣点)求出仿射变换, 接下来我们就能把仿射变换应用到图像中所有的点中,就完成了图像的仿射变换。
在这里插入图片描述
在OpenCV中,仿射变换的矩阵是一个 2 × 3 2×3 2×3的矩阵,
M = [ A B ] = [ a 00 b 01 b 0 a 10 b 11 b 1 ] M= \begin{bmatrix} A & B \\ \end{bmatrix}= \begin{bmatrix} a_{00} & b_{01} & b_{0} \\ a_{10} & b_{11} & b_{1} \end{bmatrix} M=[AB]=[a00a10b01b11b0b1]

其中左边的 2 × 2 2×2 2×2子矩阵 A A A是线性变换矩阵,右边的2×1子矩阵 B B B是平移项:
A = [ a 00 b 01 a 10 b 11 ] , B = [ b 0 b 1 ] A= \begin{bmatrix} a_{00} & b_{01} \\ a_{10} & b_{11} \end{bmatrix}, B= \begin{bmatrix} b_{0} \\ b_{1} \end{bmatrix} A=[a00a10b01b11],B=[b0b1]
对于图像上的任一位置 ( x , y ) (x,y) (x,y),仿射变换执行的是如下的操作:
T a f f i n e = A [ x y ] + B = M [ x y 1 ] T_{affine}=A \begin{bmatrix} x \\ y \end{bmatrix} +B=M \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} Taffine=A[xy]+B=M xy1

需要注意的是,对于图像而言,宽度方向是x,高度方向是y,坐标的顺序和图像像素对应下标一致。所以原点的位置不是左下角而是右上角,y的方向也不是向上,而是向下。

在仿射变换中,原图中所有的平行线在结果图像中同样平行。为了创建这个矩阵我们需要从原图像中找到三个点以及他们在输出图像中的位置。然后cv2.getAffineTransform 会创建一个 2 x 3 2x3 2x3 的矩阵,最后这个矩阵会被传给函数 cv2.warpAffine

示例

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 1 图像读取
img = cv.imread("./image/image2.jpg")

# 2 仿射变换
rows,cols = img.shape[:2]
# 2.1 创建变换矩阵
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[100,100],[200,50],[100,250]])
M = cv.getAffineTransform(pts1,pts2)
# 2.2 完成仿射变换
dst = cv.warpAffine(img,M,(cols,rows))

# 3 图像显示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img[:,:,::-1])
axes[0].set_title("原图")
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title("仿射后结果")
plt.show()

在这里插入图片描述

5 透射变换

透射变换是视角变化的结果,是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。
在这里插入图片描述
它的本质将图像投影到一个新的视平面,其通用变换公式为:
[ x ′ y ′ 1 ] = [ u v w ] [ a 00 a 01 a 02 a 10 a 11 a 12 a 20 a 21 a 22 ] \begin{bmatrix} x^{'} & y^{'} & 1 \\ \end{bmatrix}= \begin{bmatrix} u & v& w \\ \end{bmatrix} \begin{bmatrix} a_{00} & a_{01} & a_{02} \\ a_{10} & a_{11} & a_{12} \\ a_{20} & a_{21} & a_{22} \end{bmatrix} [xy1]=[uvw] a00a10a20a01a11a21a02a12a22
其中, ( u , v ) (u,v) (u,v)是原始的图像像素坐标, w w w取值为 1 1 1 ( x = x ′ / z ′ , y = y ′ / z ′ ) (x=x'/z',y=y'/z') (x=x/z,y=y/z)是透射变换后的结果。后面的矩阵称为透视变换矩阵,一般情况下,我们将其分为三部分:
T = [ a 00 a 01 a 02 a 10 a 11 a 12 a 20 a 21 a 22 ] = [ T 1 T 2 T 3 a 22 ] T= \begin{bmatrix} a_{00} & a_{01} & a_{02} \\ a_{10} & a_{11} & a_{12} \\ a_{20} & a_{21} & a_{22} \end{bmatrix}= \begin{bmatrix} T_{1} &T_{2} \\ T_{3} & a_{22} \\ \end{bmatrix} T= a00a10a20a01a11a21a02a12a22 =[T1T3T2a22]
其中: T 1 T_{1} T1表示对图像进行线性变换, T 2 T_{2} T2对图像进行平移, T 3 T_{3} T3表示对图像进行投射变换, a 22 a_{22} a22一般设为1.

在opencv中,我们要找到四个点,其中任意三个不共线,然后获取变换矩阵T,再进行透射变换。通过函数cv.getPerspectiveTransform找到变换矩阵,将cv.warpPerspective应用于此 3 x 3 3x3 3x3变换矩阵。

  1. 示例
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 1 读取图像
img = cv.imread("./image/image2.jpg")
# 2 透射变换
rows,cols = img.shape[:2]
# 2.1 创建变换矩阵
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[100,145],[300,100],[80,290],[310,300]])

T = cv.getPerspectiveTransform(pts1,pts2)
# 2.2 进行变换
dst = cv.warpPerspective(img,T,(cols,rows))

# 3 图像显示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img[:,:,::-1])
axes[0].set_title("原图")
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title("透射后结果")
plt.show()

在这里插入图片描述

6 图像金字塔

图像金字塔是图像多尺度表达的一种,最主要用于图像的分割,是一种以多分辨率来解释图像的有效但概念简单的结构。

图像金字塔用于机器视觉和图像压缩,一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低,且来源于同一张原始图的图像集合。其通过梯次向下采样获得,直到达到某个终止条件才停止采样。

金字塔的底部是待处理图像的高分辨率表示,而顶部是低分辨率的近似,层级越高,图像越小,分辨率越低。
在这里插入图片描述

  1. API
cv.pyrUp(img)       #对图像进行上采样
cv.pyrDown(img)        #对图像进行下采样
  1. 示例
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 1 图像读取
img = cv.imread("./image/image2.jpg")
# 2 进行图像采样
up_img = cv.pyrUp(img)  # 上采样操作
img_1 = cv.pyrDown(img)  # 下采样操作
# 3 图像显示
cv.imshow('enlarge', up_img)
cv.imshow('original', img)
cv.imshow('shrink', img_1)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述
总结

  1. 图像缩放:对图像进行放大或缩小
cv.resize()
  1. 图像平移:

指定平移矩阵后,调用cv.warpAffine()平移图像

  1. 图像旋转:

调用cv.getRotationMatrix2D获取旋转矩阵,然后调用cv.warpAffine()进行旋转

  1. 仿射变换:

调用cv.getAffineTransform将创建变换矩阵,最后该矩阵将传递给cv.warpAffine()进行变换

  1. 透射变换:

通过函数cv.getPerspectiveTransform()找到变换矩阵,将cv.warpPerspective()进行投射变换

  1. 金字塔

图像金字塔是图像多尺度表达的一种,使用的API:

cv.pyrUp(): 向上采样

cv.pyrDown(): 向下采样

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

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

相关文章

数据结构 | 二叉排序树

一、数据结构定义 /* 二叉排序树 */ typedef int TreeType; typedef struct BSTNode {TreeType data;struct BSTNode* lchild, * rchild; }*BSTree, BSTNode;二、方法概览 BSTNode* CreateTreeNode(TreeType data); // 创建二叉树结点 BSTNode* InsertTree(TreeType data, BS…

Vulnhub靶机PWNLAB:INIT writeup

靶机介绍 靶机下载:https://www.vulnhub.com/entry/matrix-2,279/ ​ 个人微信公众号:网络安全学习爱好者 信息搜集 arp扫描存活主机 ​​​ 根据MAC地址比较靶机IP为​192.168.30.131 ​​ nmap扫描全端口及端口服、版本 ​​​ 目录扫描123…

通信相关知识(三) 接入网

接入网的定界 接入网的功能 用户口功能、业务口功能、核心功能、传送功能、接入网系统管理功能。 ADSL 非对称数字用户线路(ADSL,Asymmetric Digital Subscriber Line)是数字用户线路(xDSL,Digital Subscriber Lin…

【Java从入门到大牛】Java基础语法

🔥 本文由 程序喵正在路上 原创,CSDN首发! 💖 系列专栏:Java从入门到大牛 🌠 首发时间:2023年7月5日 🦋 欢迎关注🖱点赞👍收藏🌟留言&#x1f43e…

黑客(自学笔记)

黑客,对很多人来说充满诱惑力。很多人可以发现这门领域如同任何一门领域,越深入越敬畏,知识如海洋,黑客也存在一些等级,参考知道创宇 CEO ic(世界顶级黑客团队 0x557 成员)的分享如下&#xff1…

第一章:项目架构演变

1、在设计系统时,应该多思考 墨菲定律 1. 任何事都没有表面上看起来那么简单。 2. 所有的事做起来都会比你预计的时间长。 3. 可能出错的事总会出错。 4. 如果你担心某种情况发生,那么它就更有可能发生。 2、在划分时,也要思考康威定律。…

centos7安装zookeeper的环境变量配置导致用户登录不了系统

废话不多说,我修改的/etc/profile,如果这个文件改错会造成所有用户都登录不了系统。 第一步:解决进不了系统 1.在登陆界面按:alt ctrlf2进入命令模式,输入密码登录后再输入: /usr/bin/sudo /usr/bin/vi /etc/profile …

Apache Doris 在拈花云科的统一数据中台实践,One Size Fits All

作者|NearFar X Lab 团队 洪守伟、陈超、周志银、左益、武超 整理|SelectDB 内容团队 导读: 无锡拈花云科技服务有限公司(以下简称拈花云科)是由中国创意文旅集成商拈花湾文旅和北京滴普科技有限公司共同孵化组建的。…

微信小程序Vant组件配置及使用

Vant Weapp 官网文档:介绍 - Vant Weapp (gitee.io) Vant Weapp GitHub地址:youzan/vant-weapp: 轻量、可靠的小程序 UI 组件库 (github.com) 本教程使用下载代码方式引入vant组件 1. 下载vant组件源码 通过git下载vant源码 git clone https://github…

【适配器模式】—— 每天一点小知识

💧 适配器模式 \color{#FF1493}{适配器模式} 适配器模式💧 🌷 仰望天空,妳我亦是行人.✨ 🦄 个人主页——微风撞见云的博客🎐 🐳 《数据结构与算法》专栏的文章图文并茂🦕…

Kafka学习笔记(基础篇)

目录 Kafka简介 消息队列 Kafka的应用场景 消息队列的两种模型 Kafka集群搭建 Kafka的生产者/消费者/工具 Kafka的基准测试工具 Kafka Java API开发 生产者程序开发 消费者程序开发 生产者使用异步方式生产消息 Kafka中的重要概念 消费者组 幂等性 事务编程 Ka…

英文单词的3σ值

最近做log的nlp,发现日志当中有一些很长的但是无意义的词汇,很影响训练模型,这边想通过单次长度去排除那些无意义词汇,去查了gpt英文单次的3σ值,记录下

谷歌浏览器中的谷歌翻译失效了?如何解决谷歌翻译不响应问题?

1 原因分析 因为谷歌把国内的服务器关了。 2 下载软件 (1)Mac OS https://github.com/Ponderfly/GoogleTranslateIpCheck/releases/download/1.6/GoogleTranslateIpCheck-mac-x64.zip(2)Windows https://github.com/Ponderfl…

【MySQL体系结构及CetOS7安装MySQL和修改密码】

MySQL体系结构及安装MySQL MySQL体系结构CentOS7安装MySQL四种方法1、离线安装2、在线安装3、通用二级制方式4、容器方式安装 设置及修改密码忘记密码恢复 MySQL体系结构 MySQL是一种常用的关系型数据库管理系统(RDBMS),其体系结构包括以下&…

ARM架构(ARM汇编指令练习)

文章目录 前言一、MOV指令二、内存访问指令1.LDR指令2.STR指令 三、数据处理指令1.ADD指令2.SUB指令3.位操作指令4.CMP指令 四、跳转指令总结 前言 本篇文章带大家来学习ARM汇编的一些常用的指令,这里指令都是非常基础的指令。 一、MOV指令 MOV(Move&…

一个 Kill 不掉的 MySQL 会话

究竟是什么原因,导致主从切换过程中存在一个无法 kill 的会话? 作者:秦广飞 爱可生 DBA 团队成员,负责项目日常问题处理及公司平台问题排查,对数据库有兴趣,对技术有想法。一入 IT 深似海,从此节…

【钱处理】商业计算怎样才能保证精度不丢失

以项目驱动学习,以实践检验真知 前言 很多系统都有「处理金额」的需求,比如电商系统、财务系统、收银系统,等等。只要和钱扯上关系,就不得不打起十二万分精神来对待,一分一毫都不能出错,否则对系统和用户来…

集群 第一章

目录 1.群集的含义 2.群集分类 3.群集架构 4.负载调度工作模式 5.lvs 虚拟服务器 6.nat 模式 lvs 负载均衡群集部署 7.总结 1.群集的含义 由多台主机构成,但对外只表现为一个整体,只提供一个访问入口(域名与IP地址)&#…

建筑师们,你们该把三维模型弄到PPT里做汇报了!

➤如何实现项目汇报效率比传统的PPT高,同时汇报效果更直观? ➤如何摆脱方案汇报只能向客户交付数据,安装专业软件查看项目成果? ➤如何将无人机航测数据、CAD图纸、BIM设计成果进行融合,挖掘出更深层次的应用&#x…

mysql体系结构及安装部署mysql

目录 1.体系结构 2.安装mysql 1.yum 源安装 2. 第二种安装方式-通用二进制方式 3.mysql改密方式 第一种,知道密码的情况下 第二种,不知道密码 1.体系结构 MySQL server连接层连接池(缓冲池)SQL层系统管理和控制工具SQL…