Python-OpenCV中的图像处理-几何变换
Python-OpenCV中的图像处理-几何变换
- 几何变换
- 图像缩放
- 图像平移
- 图像旋转
- 仿射变换
- 透视变换
 
几何变换
对图像进行各种几个变换,例如移动,旋转,仿射变换等。
图像缩放
- cv2.resize()
- cv2.INTER_AREA
- v2.INTER_CUBIC
- v2.INTER_LINEAR
res = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)
或
height, width = img.shape[:2]
res = cv2.resize(img, (2width, 2height), interpolation=cv2.INTER_CUBIC)
import numpy as np
import cv2# 图像缩放
img = cv2.imread('./resource/image/1.jpg')# 缩放 时推荐使用cv2.INTER_AREA 
# 扩展 时推荐使用cv2.INTER_CUBIC(慢) 或 cv2.INTER_LINEAR(默认使用)
# 原图放大两倍
res = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)# 或
#height, width = img.shape[:2]
#res = cv2.resize(img, (2*width, 2*height), interpolation=cv2.INTER_CUBIC)while True:cv2.imshow('res', res)cv2.imshow('img', img)if cv2.waitKey(1)&0xFF == 27:break
cv2.destroyAllWindows()
图像平移
OpenCV提供了使用函数cv2.warpAffine()实现图像平移效果,该函数的语法为
- cv2.warpAffine(src, M, (cols, rows))
- src:输入的源图像
- M:变换矩阵,即平移矩阵,M = [[1, 0, tx], [0, 1, ty]] 其中,tx和ty分别代表在x和y方向上的平移距离。
- (cols, rows):输出图像的大小,即变换后的图像大小
平移就是将对象换一个位置。如果你要沿( x, y)方向移动,移动的距离
 是( tx, ty),你可以以下面的方式构建移动矩阵:
  M = [ 1 0 t x 0 1 t y ] M=\left[ \begin{matrix} 1&0&t_x\\ 0 &1 &t_y \end{matrix} \right] M=[1001txty]
import cv2
import numpy as npimg = cv2.imread('./resource/opencv/image/messi5.jpg')# 获取图像的行和列
rows, cols = img.shape[:2]# 定义平移矩阵,沿着y轴方向向下平移100个像素点
# M = np.float32([[1, 0, 0], [0, 1, 100]])# 定义平移矩阵,沿着x轴方向向右平移50个像素点,沿着y轴方向向下平移100个像素点
M = np.float32([[1, 0, -50], [0 ,1, 100]])# 执行平移操作
result = cv2.warpAffine(img, M, (cols, rows))# 显示结果图像
cv2.imshow('result', result)
cv2.waitKey(0)

图像旋转
- cv2.getRotationMatrix2D()
 对一个图像旋转角度 θ, 需要使用到下面形式的旋转矩阵:
 M = [ c o s θ − s i n θ s i n θ c o s θ ] M=\left[ \begin{matrix} cosθ&-sinθ \\sinθ&cosθ \end{matrix} \right] M=[cosθsinθ−sinθcosθ]
import numpy as np
import cv2# 图像旋转 缩放
img = cv2.imread('./resource/opencv/image/messi5.jpg', cv2.IMREAD_GRAYSCALE)
rows,cols = img.shape# 这里的第一个参数为旋转中心,第二个为旋转角度,第三个为旋转后的缩放因子
# 可以通过设置旋转中心,缩放因子,以及窗口大小来防止旋转后超出边界的问题
M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 0.6)
print(M)# 第三个参数是输出图像的尺寸中心
dst = cv2.warpAffine(img, M, (2*cols, 2*rows))
while (1):cv2.imshow('img', dst)if cv2.waitKey(1)&0xFF == 27:break
cv2.destroyAllWindows()

 dst = cv2.warpAffine(img, M, (1cols, 1rows))
 
仿射变换
在仿射变换中,原图中所有的平行线在结果图像中同样平行。为了创建这个矩阵我们需要从原图像中找到三个点以及他们在输出图像中的位置。然后cv2.getAffineTransform 会创建一个 2x3 的矩阵,最后这个矩阵会被传给函数 cv2.warpAffine。
import numpy as np
import cv2
from matplotlib import pyplot as plt# 仿射变换
img = cv2.imread('./resource/opencv/image/messi5.jpg', cv2.IMREAD_COLOR)
rows, cols, ch = img.shape
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100], [200,50], [100,250]])# 行,列,通道数
M = cv2.getAffineTransform(pts1, pts2)
dts = cv2.warpAffine(img, M, (cols, rows))plt.subplot(121), plt.imshow(img), plt.title('Input')
plt.subplot(122), plt.imshow(dts), plt.title('Output')
plt.show()

透视变换
对于视角变换,我们需要一个 3x3 变换矩阵。在变换前后直线还是直线。要构建这个变换矩阵,你需要在输入图像上找 4 个点,以及他们在输出图像上对应的位置。这四个点中的任意三个都不能共线。这个变换矩阵可以有函数cv2.getPerspectiveTransform() 构建。然后把这个矩阵传给函数cv2.warpPerspective()
import numpy as np
import cv2
from matplotlib import pyplot as plt# 透视变换
img = cv2.imread('./resource/opencv/image/sudoku.png', cv2.IMREAD_COLOR)
rows,cols,ch = img.shape
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)pts1 = np.float32([[60,80],[368,65],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])M = cv2.getPerspectiveTransform(pts1, pts2)
dst = cv2.warpPerspective(img, M, (400, 400))plt.subplot(121), plt.imshow(img), plt.title('Input')
plt.subplot(122), plt.imshow(dst), plt.title('Output')
plt.show()

相关文章:
 
Python-OpenCV中的图像处理-几何变换
Python-OpenCV中的图像处理-几何变换 几何变换图像缩放图像平移图像旋转仿射变换透视变换 几何变换 对图像进行各种几个变换,例如移动,旋转,仿射变换等。 图像缩放 cv2.resize() cv2.INTER_AREAv2.INTER_CUBICv2.INTER_LINEAR res cv2.r…...
 
前端JavaScript入门-day08-正则表达式
(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 介绍 语法 元字符 边界符 量词 字符类: 修饰符 介绍 正则表达式(Regular …...
 
ML类CFAR检测器在不同环境中检测性能的分析
摘要:该文是楼主翻阅书籍以及一些论文总结出来的关于ML(均值)类CFAR检测器在不同环境中的性能对比,以及优缺点的总结,可以帮助大家面对不同情形如何选择CFAR问题。由于楼主见识短浅,文中难免出现不足之处,望各位指出。…...
element-ui 路由动态加载功能
第一步 自定义默认的静态路由像登陆和首页这些一般开放的页面,主要代码如下: const router new Router({routes: [{path: "/login/index",component: () > import("../components/page/login/index.vue"),meta: {title: "登录",k…...
 
(学习笔记-进程管理)进程调度
进程都希望自己能够占用CPU进行工作,那么这涉及到前面说过的进程上下文切换。 一旦操作系统把进程切换到运行状态,也就意味着该进程占用着CPU在执行,但是操作系统把进程切换到其他状态的时候,就不能在CPU中执行了,于是…...
十分钟python入门 正则表达式
正则常见的三种功能,它们分别是:校验数据的有效性、查找符合要求的文本以及对文本进行切割和替换等操作。 1.元字符 所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符 元字符大致分成这几类:表示单个特殊字符的,表示…...
关于数据拷贝赋值方法
系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言一、关于数据拷贝赋值方法1、最基础数据类型的变量才可以直接拷贝赋值2、自己定义的大数据类型或者时类实例化的对象不可以直接拷贝赋值1、方法一:…...
 
Effective Java笔记(32)谨慎并用泛型和可变参数
故事的小黄花 从出生那年就飘着 童年的荡秋千 随记忆一直晃到现在 可变参数( vararg ) 方法(详见第 53 条)和泛型都是在 Java 5 中就有了,因此你可能会期待它们可以良好地相互作用;遗憾的是,它们…...
 
数据结构——双向链表
双向链表实质上是在单向链表的基础上加上了一个指针指向后面地址 单向链表请参考http://t.csdn.cn/3Gxk9 物理结构 首先我们看一下两种链表的物理结构 我们可以看到:双向在单向基础上加入了一个指向上一个地址的指针,如此操作我们便可以向数组一样操作…...
Declare 关键字在 TypeScript 中如何正确使用?
如果您编写 TypeScript 代码的时间足够长,您就已经看到过declare关键字。但它有什么作用,为什么要使用它? declare关键字告诉 TypeScript 编译器存在一个对象并且可以在代码中使用。 本文解释了声明关键字并通过代码示例展示了不同的用例。 定义 在 TypeScript 中,decl…...
 
ChatGPT将会成为强者的外挂?—— 提高学习能力
目录 前言 一、提高学习力 🧑💻 1. 快速找到需要的知识 2. 组合自己的知识体系 3. 内化知识技能 二、提问能力❗ 三、思维、创新能力 🌟 1. 批判性思维 1.1 八大基本结构进行批判性提问 1.2 苏格拉底的提问分类方法 2. 结构化思…...
AUTOSAR规范与ECU软件开发(基础篇)1.3 车用控制器软件标准(从OSEK到AUTOSAR)
目录 AUTOSAR的前世与今生 1.1~1.3篇幅小结 AUTOSAR的前世与今生 为了迎合汽车高精度、 高实时性、 高可靠性控制的需要, 嵌入式实时操作系统(Real Time Operating System, RTOS) 逐渐在ECU中使用。与此同时, 由于不同实时操作系统间应用程序接口(Application Programmi…...
 
R语言5_安装Giotto
环境Ubuntu22/20, R4.1. 已开启科学上网。 第一步,更新服务器环境,进入终端,键入如下命令, apt-get update apt install libcurl4-openssl-dev libssl-dev libxml2-dev libcairo2-dev libgtk-3-dev libhdf5-dev libmagick9-dev …...
centos按用户保存历史执行命令
centos7 按用户记录历史命令的方法 在/etc/profile文件中添加以下代码。 添加完成后执行source /etc/profile 用户重新登录即可发现history被清空了。这时可以去看/usr/share/.history文件夹,该文件夹保存了所有用户每次登录所执行过的的操作记录。 文件路径为 /usr…...
【力扣】61. 旋转链表 <快慢指针>
【力扣】61. 旋转链表(每个节点向右移k个单位) 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。 示例 1: 输入:head [1,2,3,4,5], k 2 输出:[4,5,1,2,3] 示例 2&a…...
 
编写一个指令(v-focus2end)使输入框文本在聚焦时焦点在文本最后一个位置
项目反馈输入框内容比较多时候,让鼠标光标在最后一个位置,心想什么奇葩需求,后面试了一下,是有点影响体验,于是就有了下面的效果,我目前的项目都是若依的架子,用的是vue2版本。vue3的朋友想要使…...
 
Virtualbox设置访问外网以及主机和虚拟机互通
参考链接 1、设置使虚拟机访问外网。选中虚拟机,右击选择“设置”。 2、在设置中选择“网络”,然后点击“网卡1”,选择“网络地址转换(NAT)”模式,点击“确定”。 4.此时你的虚拟机就可以访问外网了 5…...
请简述React是什么?React的主要特点有哪些?React中有哪些主要组件?
1、请简述React是什么? React是一个用于构建用户界面的JavaScript库,它由Facebook开发并开源。React的主要特点是其数据驱动和组件化的设计理念。它允许开发者将复杂的界面分解为简单的组件,并将这些组件以数据流的方式组合在一起࿰…...
 
DevOps最佳实践和工具在本地环境中的概述
引言 最近,我进行了一次网上搜索,以寻找DevOps的概述,尽管有大量的DevOps工具和实践,但我无法找到一个综合的概述。因此,我开始了对DevOps生态系统和最佳实践的梳理,以创建一个整体视图,方便后续研究实践 C…...
kafka和rabbitmq之间的区别以及适用场景
Kafka 和 RabbitMQ 都是流行的消息传递系统,用于实现分布式系统中的消息传递、事件处理和数据流。它们在设计和适用场景上有一些不同,下面详细介绍它们之间的区别和适用场景。 Kafka 特点和优势: 高吞吐量: Kafka 的设计目标是实…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
 
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
 
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
 
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
 
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...
