图像旋转:从原理到 OpenCV 实践

在图像处理领域,图像旋转是一项基础且重要的操作。它不仅可以改变图像的方向,还在许多计算机视觉任务中发挥着关键作用,比如目标检测、图像配准等。本文将深入探讨图像旋转的原理,并结合 OpenCV 库提供具体的实现代码。

一、图像旋转的原理

1. 单点旋转

我们从最简单的单点旋转开始分析。假设旋转中心为坐标系原点 \(O(0, 0)\),有一点 \(P_0(x_0, y_0)\),它绕原点顺时针旋转 \(\theta\) 角后得到点 \(P(x, y)\)。通过三角函数关系,我们可以推导出以下公式:

用矩阵表示为:

然而,在 OpenCV 中,旋转中心是图像的左上角,且逆时针为正方向,所以旋转矩阵变为:

如果要围绕任意点进行旋转,我们需要先将旋转点移到原点,进行旋转操作,再将旋转点移回原来的位置。这涉及到平移矩阵,最终得到的仿射变换矩阵为:

2. 图片旋转

图像旋转实际上就是将图像中的每个像素点代入仿射变换矩阵,得到旋转后的新坐标。在 OpenCV 中,我们可以使用 cv2.getRotationMatrix2D() 函数来获取仿射变换矩阵,该函数需要三个参数:旋转中心点 Center、旋转角度 Angle 和缩放比例 Scale

3. 插值方法

在图像旋转过程中,由于三角函数的计算结果可能是小数,像素点旋转后的取整结果可能会重合,导致部分原始像素信息丢失。同时,图像缩放时也会出现像素点数量变化的问题。为了解决这些问题,我们需要使用插值方法来计算旋转后图像中每个像素点的像素值。常见的插值方法有以下几种:

3.1 最近邻插值(CV2.INTER_NEAREST

目标点与原图像点之间坐标的计算公式为:

最近邻插值的原则是目标像素点的像素值与计算出来的对应像素点的像素值相同,若出现小数部分则进行取整。

3.2 双线性插值(CV2.INTER_LINEAR

双线性插值是在水平和垂直方向上进行线性插值。假设要查找目标图像上坐标为 (x', y') 的像素值,在原图像上对应的浮点坐标为 (x, y),我们需要找到原图像上最接近 (x, y) 的四个像素点,然后分别在水平和垂直方向上进行线性插值。为了解决坐标系不同和图像位置偏移的问题,OpenCV 对公式进行了优化:

3.3 像素区域插值(cv2.INTER_AREA

像素区域插值在缩小图像时会变成均值滤波器,对区域内的像素值取平均值;在放大图像时,如果放大比例是整数倍,其工作原理与最近邻插值类似,否则调用双线性插值进行放大。

3.4 双三次插值(cv2.INTER_CUBIC

双三次插值需要原图像中近邻的 16 个点来加权,通过 BiCubic 基函数求出 16 个像素点的权重,目标图像像素值等于这 16 个像素点的加权叠加。

3.5 Lanczos 插值(cv2.INTER_LANCZOS4

Lanczos 插值与双三次插值思想类似,但需要原图像周围 8×8 的像素点,使用不同的权重公式计算权重。

4. 边缘填充方式

在图像旋转后,可能会出现部分区域为空的情况,因此需要对这些区域进行填充。常见的边缘填充方式有以下几种:

  • 边界复制(BORDER_REPLICATE:将边界处的像素值进行复制,作为边界填充的像素值。
  • 边界反射(BORDER_REFLECT:根据原图的边缘进行反射。
  • 边界反射 101(BORDER_REFLECT_101:与边界反射不同,不再反射边缘的像素点。
  • 边界常数(BORDER_CONSTANT:指定一个常数值作为填充值,默认值为 0。
  • 边界包裹(BORDER_WRAP:一种特殊的填充方式。

二、OpenCV 实现图像旋转

以下是使用 OpenCV 实现图像旋转的示例代码:

import cv2def test001():img = cv2.imread("./opencv_work/src/rabbit.png")h, w, c = img.shapem = cv2.getRotationMatrix2D((h / 2, w / 2), 45, 2)img_rotate = cv2.warpAffine(img, m, (2 * w, 2 * h))cv2.imshow("img", img)cv2.imshow("img_rotate", img_rotate)cv2.waitKey(0)if __name__ == '__main__':test001()

在上述代码中,我们首先使用 cv2.imread() 函数读取图像,然后使用 cv2.getRotationMatrix2D() 函数获取仿射变换矩阵,最后使用 cv2.warpAffine() 函数进行图像旋转。

三、总结

图像旋转是图像处理中的重要操作,理解其原理对于深入学习计算机视觉和图像处理至关重要。OpenCV 提供了方便的函数来实现图像旋转,同时也支持多种插值方法和边缘填充方式,我们可以根据具体需求选择合适的方法。在实际应用中,我们需要综合考虑计算速度和图像质量,选择最适合的参数。

希望本文能帮助你更好地理解图像旋转的原理和实现方法,欢迎在评论区留言交流。

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

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

相关文章

微服务架构下的抉择:Consul vs. Eureka,服务发现该如何选型?

微服务架构下的抉择:Consul vs. Eureka,服务发现该如何选型? 引言 想象一下,我们正在构建一个大型电商平台。在“双十一”大促期间,流量洪峰涌入,订单服务、商品服务、用户服务等都需要弹性伸缩&#xff…

基于Java+SpringBoot的宠物爱心组织管理系统

源码编号:S572 源码名称:基于SpringBoot的宠物爱心组织管理系统 用户类型:双角色,用户、管理员 数据库表数量:15 张表 主要技术:Java、Vue、ElementUl 、SpringBoot、Maven 运行环境:Windo…

数字样机:改写卫星物联网的研制范式

01. 卫星物联网:技术边界的自然延伸 随着物联网在城市、工业、农业等领域的广泛部署,万物互联的愿景正在不断逼近技术的边界。尤其是在海洋、沙漠、高原、边远山区等传统通信网络难以覆盖的区域,人们对无盲点物联网连接的需求日益增强。这一…

springsecurity---使用流程、加密机制、自定义密码匹配器、token字符串生成

目录 权限控制 相关框架 SpringSecurity springsecurity使用流程 1、搭建环境实现默认用户名和密码登录 2、使用数据库表中定义好的用户名和密码访问实现等值密码匹配 1)sql文件 2)搭建jdbc或者mybatis或者mybatis-plus环境 3)配置mybatis-plus环…

在 Ubuntu 22.04 上使用 Minikube 部署 Go 应用到 Kubernetes

文章目录 环境说明目标步骤与问题解决1. 构建 Go 应用和 Docker 镜像问题 1:Go 依赖下载卡住问题 2:Docker 镜像拉取失败 2. 设置 Minikube 集群安装 Minikube问题 3:Minikube 启动失败问题 4:Minikube 镜像拉取失败 3. 部署 Kube…

Android Studio-Git的使用指南

一、git的基本使用流程 git clone 克隆远程资源到本地目录,作为工作目录;然后在本地的克隆目录上添加或修改文件;如果远程修改了,需要同步远程的内容,直接git pull就可以更新本地的文件;本地在修改之后&…

【github】想fork的项目变为私有副本

在 GitHub 上,所有的 fork 都会继承其上游仓库(upstream)的可见性(visibility)设置: 可见性继承 如果你 fork 的原仓库是 public,那么你的 fork 也必须是 public。如果原仓库是 private&#xf…

微软发布新一代存储优化型虚拟机:Azure Laosv4、Lasv4 和 Lsv4 系列

微软宣布,全新一代存储优化型虚拟机——Azure Laosv4、Lasv4 和 Lsv4 系列已正式面世。 与前一代虚拟机系列相比,全新的 L 系列虚拟机实现了重大突破。它支持高达 23TB 的本地 NVMe SSD,在 CPU、网络以及远程存储性能方面均有显著提升。该系…

python调用pybind11导出的pyd,出现UnicodeDecodeError

python调用pybind11导出的pyd,出现UnicodeDecodeError 1. 问题描述 举个例子,当有以下C代码以及Pybind11的绑定代码时,在python访问包含中文的Name和Value会有UnicodeDecodeError的异常! class VxUserProp{public:VxUserProp();…

MySQL别名在GROUP BY中的使用规则

-- 设置变量:SET earliest_date ... 用于定义并赋值一个用户变量 earliest_date。 -- 用户定义的变量必须以 符号开头,例如 earliest_date。 -- 符号是MySQL中用户变量的标识符,用于区分系统变量和用户变量。 SET earliest_date (SELECT …

2025.7.4总结

感恩环节:感谢今日工作顺利度过,明天终于能美美的睡个懒觉了。感谢这周有个美好的双休。今日去实验室参观设备,感谢我的一个同事解答了我关于硬件设备与所做软件业务之间的关系,通过控制器控制网元等相关设备,同时,虽然…

Prompt 精通之路(五)- 构建你的“AI 指令系统”:超越简单提问的 CRISPE 与 APE 框架

🚀 Prompt 精通之路:系列文章导航 第一篇:[本文] AI 时代的新语言:到底什么是 Prompt?为什么它如此重要?第二篇:告别废话!掌握这 4 个黄金法则,让你的 Prompt 精准有效第…

#NFT艺术品哈希值唯一性与《民法典》“网络虚拟财产”认定的冲突

首席数据官高鹏律师数字经济团队创作,AI辅助 一、当区块链的「绝对唯一」遇上法律的「弹性空间」 每个NFT艺术品背后的哈希值,都像用数学密码刻在区块链上的指纹——世界上没有任何两个完全相同的编码。这种由0和1构筑的「数字DNA」,被技术信…

【arXiv2025】计算机视觉|即插即用|LBMamba:革新视觉模型效率,性能炸裂

论文地址:https://arxiv.org/pdf/2506.15976 代码地址:https://github.com/CiaoHe/bi-mamba 关注UP CV缝合怪,分享最计算机视觉新即插即用模块,并提供配套的论文资料与代码。 https://space.bilibili.com/473764881 摘要 Mamba…

【狂飙AGI】第7课:AGI-行业大模型(系列1)

目录 (一)服装史的GPT时刻(二)AI多学科诊疗系统(三)医疗大模型(四)生物医药大模型(五)教育大模型(六)心理大模型(七&#…

(LeetCode 每日一题) 3307. 找出第 K 个字符 II (位运算、数学)

题目&#xff1a;3307. 找出第 K 个字符 II 思路&#xff1a;位运算&#xff0c;时间复杂度0(logk)。 当2^(i-1) <k 且 2^i>k &#xff0c;说明k在K2^i的右半段 &#xff0c;k和其前半段的某个字符有关系 即当k>K时&#xff0c;k是由k-K位置上的字符变化而来&#xf…

国产MCU学习Day4——CW32F030C8T6:独立看门狗功能全解析

CW32F030C8T6 看门狗功能概述 CW32F030C8T6 是芯源半导体&#xff08;WCH&#xff09;推出的 Cortex-M0 内核微控制器&#xff0c;内置独立看门狗&#xff08;IWDG&#xff09;和窗口看门狗&#xff08;WWDG&#xff09;&#xff0c;用于检测和恢复系统异常状态。 一.独立看门…

SAP升级过程中如何确保数据安全?

目录 升级过程中可能遇到的数据风险 升级前的准备工作 升级过程中的保护措施 升级后的验证工作 在数字化转型浪潮中&#xff0c;SAP系统作为企业核心业务运营的系统&#xff0c;其升级过程不仅关乎技术架构的革新&#xff0c;更直接关系到企业最宝贵的资产——数据安全。一…

Vue 3 + Element Plus 常见开发问题与解决方案手册

&#x1f31f;Vue 3 Element Plus 常见开发问题与解决方案手册 &#x1f9e0; 本文整理了常见但容易混淆的几个 Vue 3 前端开发问题&#xff0c;包括插槽、原型链、响应式数据处理、v-model 报错、样式阴影控制等&#xff0c;建议收藏学习&#xff01; &#x1f4cc;一、动态插…

Spring Boot + 本地部署大模型实现:安全性与可靠性保障

在将大语言模型集成到 Spring Boot 应用中时&#xff0c;安全性和可靠性是两个关键因素。本地部署的大模型虽然提供了强大的功能&#xff0c;但也可能带来一些安全风险&#xff0c;如数据泄露、模型被恶意利用等。本文将介绍如何在 Spring Boot 应用中保障本地部署大模型的安全…