当前位置: 首页 > news >正文

《数字图像处理-OpenCV/Python》连载(41)图像的旋转

《数字图像处理-OpenCV/Python》连载(41)图像的旋转


本书京东优惠购书链接:https://item.jd.com/14098452.html
本书CSDN独家连载专栏:https://blog.csdn.net/youcans/category_12418787.html

在这里插入图片描述


第 6 章 图像的几何变换


几何变换分为等距变换、相似变换、仿射变换和投影变换,是指对图像的位置、大小、形状和投影进行变换,将图像从原始平面投影到新的视平面。OpenCV图像的几何变换,本质上是将一个多维数组通过映射关系转换为另一个多维数组。


本章内容概要

  • 介绍仿射变换,学习使用仿射变换矩阵实现图像的仿射变换。
  • 学习使用函数实现图像的平移、缩放、旋转、翻转和斜切。
  • 介绍投影变换,学习使用投影变换矩阵实现图像的投影变换。
  • 介绍图像的重映射,学习使用映射函数实现图像的自定义变换和动态变换。

6.1 图像的旋转

旋转变换属于等距变换,变换后图像的长度和面积不变。
图像以左上角(0,0)为旋转中心、以旋转角度 θ 顺时针旋转,可以构造旋转变换矩阵 MAR,通过函数 cv.warpAffine 计算旋转变换图像。

[ x ~ y ~ 1 ] = M A R [ x y 1 ] , M A R = [ c o s θ − s i n θ 0 s i n θ c o s θ 0 0 0 1 ] \begin{bmatrix} \tilde{x}\\ \tilde{y}\\ 1 \end{bmatrix} = M_{AR} \begin{bmatrix} x\\ y\\ 1 \end{bmatrix} ,\hspace{1em} M_{AR} = \begin{bmatrix} cos \theta &-sin \theta &0\\ sin \theta &cos \theta &0\\ 0 &0 &1 \end{bmatrix} x~y~1 =MAR xy1 ,MAR= cosθsinθ0sinθcosθ0001

图像以任意点(x,y)为旋转中心、以旋转角度 顺时针旋转,可以先将原点平移到旋转中心(x,y),再对原点进行旋转处理,最后反向平移回坐标原点。

OpenCV中的函数cv.getRotationMatrix2D可以计算以任意点为中心的旋转变换矩阵。

函数原型

cv.getRotationMatrix2D(center, angle, scale) → M

函数cv.getRotationMatrix2D能根据旋转中心和旋转角度计算旋转变换矩阵M:

M = [ α β ( 1 − α ) x − β y − β α β x + ( 1 − α ) y ] M = \begin{bmatrix} \alpha & \beta &(1-\alpha)x-\beta y\\ -\beta &\alpha &\beta x +(1-\alpha) y \end{bmatrix} M=[αββα(1α)xβyβx+(1α)y]

参数说明

  • center:旋转中心坐标,格式为元组(x,y)。
  • angle:旋转角度,角度制,以逆时针方向旋转。
  • scale:缩放系数,是浮点型数据。
  • M:旋转变换矩阵,是形状为(2,3)、类型为np.float32的Numpy数组。

注意问题

  • (1)函数可以直接获取以任意点为中心的旋转变换矩阵,不需要额外进行平移变换。

  • (2) 如果旋转图像的尺寸与原始图像的尺寸相同,则四角的像素会被切除(见图6-3(2))。为了保留原始图像的内容,需要在旋转的同时对图像进行缩放,或将旋转图像的尺寸调整为:

W r o t = w c o s θ + h s i n θ H r o t = h c o s θ + w s i n θ W_{rot} = w cos \theta+ h sin \theta \\ H_{rot} = h cos \theta+ w sin \theta Wrot=wcosθ+hsinθHrot=hcosθ+wsinθ
式中,w、h分别为原始图像的宽度与高度; 、 分别为旋转图像的宽度与高度。

  • (3) 缩放系数scale在旋转的同时能进行缩放,但水平、垂直方向必须使用相同的缩放比例。

函数cv.rotate用于直角旋转,旋转角度为90度、180度或270度。该方法通过矩阵转置实现,运行速度极快。

函数原型

cv.rotate(src, rotateCode[, dst]) → dst

参数说明

  • src:输入图像,是Numpy数组。
  • dst:输出图像,类型与src相同,图像尺寸由旋转角度确定。
  • rotateCode:旋转标志符。
    • ROTATE_90_CLOCKWISE:顺时针旋转90度。
    • ROTATE_180:顺时针旋转180度。
    • ROTATE_90_COUNTERCLOCKWISE:顺时针旋转270度。

注意问题

旋转角度为180度时,输出图像的尺寸与输入图像的尺寸相同;旋转角度为90度或180度时,输出图像的高度和宽度分别等于输入图像的宽度和高度。


【例程0603】图像的旋转

本例程介绍以原点为旋转中心、以任意点为旋转中心旋转图像,以及图像的直角旋转。


# 【0603】图像的旋转
import cv2 as cv
import numpy as np
from matplotlib import pyplot as pltif __name__ == '__main__':img = cv.imread("../images/Fig0301.png")  # 读取彩色图像(BGR)height, width = img.shape[:2]  # 图像的高度和宽度# (1) 以原点为旋转中心x0, y0 = 0, 0  # 以左上角顶点 (0,0) 作为旋转中心theta, scale = 30, 1.0  # 逆时针旋转 30 度,缩放系数 1.0MAR0 = cv.getRotationMatrix2D((x0,y0), theta, scale)  # 旋转变换矩阵imgRot1 = cv.warpAffine(img, MAR0, (width, height))  # (2) 以任意点为旋转中心x0, y0 = width//2, height//2  # 以图像中心作为旋转中心angle = theta * np.pi/180  # 弧度->角度wRot = int(width * np.cos(angle) + height * np.sin(angle))  # 调整宽度hRot = int(height * np.cos(angle) + width * np.sin(angle))  # 调整高度scale = width/wRot  # 根据 wRot 调整缩放系数MAR1 = cv.getRotationMatrix2D((x0,y0), theta, 1.0)  # 逆时针旋转 30 度,缩放系数 1.0MAR2 = cv.getRotationMatrix2D((x0,y0), theta, scale)  # 逆时针旋转 30 度,缩放比例 scaleimgRot2 = cv.warpAffine(img, MAR1, (height, width), borderValue=(255,255,255))  # 白色填充imgRot3 = cv.warpAffine(img, MAR2, (height, width))  # 调整缩放系数,以保留原始图像的内容print(img.shape, imgRot2.shape, imgRot3.shape, scale)# (3) 图像的直角旋转imgRot90 = cv.rotate(img, cv.ROTATE_90_CLOCKWISE)  # 顺时针旋转 90度imgRot180 = cv.rotate(img, cv.ROTATE_180)  # 顺时针旋转 180度imgRot270 = cv.rotate(img, cv.ROTATE_90_COUNTERCLOCKWISE)  # 顺时针旋转 270度plt.figure(figsize=(9, 6))plt.subplot(231), plt.title("1.Rotate around the origin"), plt.axis('off')plt.imshow(cv.cvtColor(imgRot1, cv.COLOR_BGR2RGB))plt.subplot(232), plt.title("2.Rotate around the center"), plt.axis('off')plt.imshow(cv.cvtColor(imgRot2, cv.COLOR_BGR2RGB))plt.subplot(233), plt.title("3.Rotate and resize"), plt.axis('off')plt.imshow(cv.cvtColor(imgRot3, cv.COLOR_BGR2RGB))plt.subplot(234), plt.title("4.Rotate 90 degrees"), plt.axis('off')plt.imshow(cv.cvtColor(imgRot90, cv.COLOR_BGR2RGB))plt.subplot(235), plt.title("5.Rotate 180 degrees"), plt.axis('off')plt.imshow(cv.cvtColor(imgRot180, cv.COLOR_BGR2RGB))plt.subplot(236), plt.title("6.Rotate 270 degrees"), plt.axis('off')plt.imshow(cv.cvtColor(imgRot270, cv.COLOR_BGR2RGB))plt.tight_layout()plt.show()

程序说明:
运行结果,图像的旋转如图6-3所示。
(1) 图6-3(1)~(3)用函数cv.getRotationMatrix2D计算旋转变换矩阵后,通过函数cv.warpAffine计算旋转变换图像。图6-3(1)以图像原点,即左上角为中心旋转,图6-3(2)和图6-3(3)围绕图像中心点旋转变换。
(2) 图像尺寸不变,中心旋转后四角像素被切除(见图6-3(2))。在计算旋转变换矩阵时使用了缩放系数,使旋转图像保留了原始图像的内容(见图6-3(3))。
(3) 图6-3(4)~(6)所示都是直角旋转,使用函数cv.rotate通过矩阵转置实现。


在这里插入图片描述

*图6-3 图像的旋转


版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/134317103)
Copyright 2023 youcans, XUPT
Crated:2023-11-11

欢迎关注本书CSDN独家连载专栏
《数字图像处理-OpenCV/Python》连载: https://blog.csdn.net/youcans/category_12418787.html

相关文章:

《数字图像处理-OpenCV/Python》连载(41)图像的旋转

《数字图像处理-OpenCV/Python》连载(41)图像的旋转 本书京东优惠购书链接:https://item.jd.com/14098452.html 本书CSDN独家连载专栏:https://blog.csdn.net/youcans/category_12418787.html 第 6 章 图像的几何变换 几何变换分…...

案例 - 拖拽上传文件,生成缩略图

直接看效果 实现代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>拖拽上传文件</title>&l…...

PHP 使用递归方式 将其二维数组整合为层级树 其中层级id 为一个uuid的格式 造成的诡异问题 已解决

不啰嗦 直接上源代码 <?php function findChildren($list, $p_id){$r array();foreach ($list as $k > $item) {if ($item[fid] $p_id) {unset($list[$k]);$length count($r);$r[$length] $item;if ($t findChildren($list, $item[id])) {$r[$length][children] …...

rv1126-rv1109-添加分区,定制固件,开机挂载功能

===================================================================== 修改分区: 这里是分区的txt文件选择; 这里是分区的划分,我这里回车了,方便看 FIRMWARE_VER: 8.1 MACHINE_MODEL: RV1126 MACHINE_ID: 007 MANUFACTURER: RV1126 MAGIC: 0x5041524B ATAG: 0x00200…...

一台电脑使用多个gitee账号,以及提交忽略部分文件

目录 ​编辑 一&#xff1a;前言 二&#xff1a;解决方法 三&#xff1a;提交gitee时忽略文件 一&#xff1a;前言 在开发中&#xff0c;我们拥有不止一个 gitee 账号&#xff0c;通常而言一个是公司的&#xff0c;一个是私人的。有时候我们在公司写了一些自己的东西&#…...

解析邮件文本内容; Mime文本解析; MimeStreamParser; multipart解析

原始文本 ------_Part_46705_715015081.1699589700255 Content-Type: text/html;charsetUTF-8 Content-Transfer-Encoding: base64PGh0bWwCiAgICA8aGVhZD4KICAgICAgICA8bWV0YSBodHRwLW VxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRt bDsgY2hhcnNldD1VVEYtOCICiAgICAgIC…...

获取请求IP以及IP解析成省份

某些业务需要获取请求IP以及将IP解析成省份之类的&#xff0c;于是我写了一个工具类&#xff0c;可以直接COPY /*** IP工具类* author xxl* since 2023/11/9*/ Slf4j public class IPUtils {/*** 过滤本地地址*/public static final String LOCAL_ADDRESS "127.0.0.1&quo…...

YOLOv8-seg改进:复现HIC-YOLOv5,HIC-YOLOv8-seg助力小目标分割

🚀🚀🚀本文改进:HIC-YOLOv8-seg:1)添加一个针对小物体的额外预测头,以提供更高分辨率的特征图2)在backbone和neck之间采用involution block来增加特征图的通道信息;3)在主干网末端加入 CBAM 的注意力机制; 🚀🚀🚀HIC-YOLOv8-seg小目标分割检测&复杂场景…...

vscode 终端进程启动失败: shell 可执行文件“C:\Windows\System32\WindowsPower

vscode 终端进程启动失败: shell 可执行文件“C:\Windows\System32\WindowsPower 第一次用vscode&#xff0c;然后遇到这个问题&#xff0c;在设置里搜索 terminal.integrated.defaultProfile.windows 将这里的null改成"Command Prompt" 重启就可以了...

【中间件篇-Redis缓存数据库02】Redis高级特性和应用(慢查询、Pipeline、事务、Lua)

Redis高级特性和应用(慢查询、Pipeline、事务、Lua) Redis的慢查询 许多存储系统&#xff08;例如 MySQL)提供慢查询日志帮助开发和运维人员定位系统存在的慢操作。所谓慢查询日志就是系统在命令执行前后计算每条命令的执行时间&#xff0c;当超过预设阀值,就将这条命令的相关…...

栈 和 队列

什么是栈? 一种特殊的线性表&#xff0c;只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出&#xff08;LIFO - Last In First Out&#xff09;的原则。   从数据结构的角度来看&…...

【推荐】一款AI写作大师、问答、绘画工具-「智元兔 AI」

在当今技术飞速发展的时代&#xff0c;越来越多的领域开始应用人工智能&#xff08;Artificial Intelligence&#xff0c;简称AI&#xff09;。其中&#xff0c;AI写作工具备受瞩目&#xff0c;备受推崇。在众多的选择中&#xff0c;智元兔AI是一款在笔者使用过程中非常有帮助的…...

阿里云付费用户破100万 用户规模亚洲最大

导读阿里巴巴集团公布2018财年第一季度财报&#xff0c;阿里云达到一个重要里程碑&#xff0c;云计算付费用户数量首次超过100万&#xff0c;成为亚洲首家达到百万级用户规模的云计算公司。同时&#xff0c;企业级市场被云计算人工智能等新技术全面激活&#xff0c;推动该季度营…...

人工智能基础——Python:Matplotlib与绘图设计

人工智能的学习之路非常漫长&#xff0c;不少人因为学习路线不对或者学习内容不够专业而举步难行。不过别担心&#xff0c;我为大家整理了一份600多G的学习资源&#xff0c;基本上涵盖了人工智能学习的所有内容。点击下方链接,0元进群领取学习资源,让你的学习之路更加顺畅!记得…...

Ubuntu 配置 Github 的 SSH keys

先进入已有的 Git 目录或使用新建的一个 Git 仓库下。 设置 Github 用户名和邮箱&#xff1a; $ git config --global user.name [Github用户名] $ git config --global user.email [Github认证邮箱]生成 SSH 密钥文件&#xff1a; $ ssh-keygen -t rsa -C [Github认证邮箱]…...

Flink—— Flink Data transformation(转换)

Flink数据算子转换有很多类型&#xff0c;各位看官看好&#xff0c;接下来&#xff0c;演示其中的十八种类型。 1.Map&#xff08;映射转换&#xff09; DataStream → DataStream 将函数作用在集合中的每一个元素上,并返回作用后的结果&#xff0c;其中输入是一个数据流&…...

前端读取文件当文件选择相同文件名的文件,内容不会变化

前端读取文件当文件选择相同文件名的文件&#xff0c;内容不会变化 今天遇到个奇怪的bug&#xff0c;使用打开文件&#xff0c;并选择文件时&#xff0c;正常情况会读取文件信息。 但是如果先选择相同的文件名&#xff0c;则内容不会发生变化。 先说结论 只要不使用事件中e…...

PHP 服装销售管理系统mysql数据库web结构layUI布局apache计算机软件工程网页wamp

一、源码特点 PHP 服装销售管理系统是一套完善的web设计系统mysql数据库 &#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 php服装销售管理系统1 二、功能介绍 (1)员工管理&#xff1a;对员工信息…...

用于图像处理的高斯滤波器 (LoG) 拉普拉斯

一、说明 欢迎来到拉普拉斯和高斯滤波器的拉普拉斯的故事。LoG是先进行高斯处理&#xff0c;继而进行拉普拉斯算子的图像处理算法。用拉普拉斯具有过零功能&#xff0c;实现边缘岭脊提取。 二、LoG算法简述 在这篇博客中&#xff0c;让我们看看拉普拉斯滤波器和高斯滤波器的拉普…...

【h5 uniapp】 滚动 滚动条,数据跟着变化

uniapp项目 需求&#xff1a; 向下滑动时&#xff0c;数据增加&#xff0c;上方的日历标题日期也跟着变化 向上滑动时&#xff0c;上方的日历标题日期跟着变化 实现思路&#xff1a; 初次加载目前月份的数据 以及下个月的数据 this.getdate()触底加载 下个月份的数据 onReach…...

植物大战僵尸修改器PvZ Toolkit:新手到高手的5大核心功能全解析

植物大战僵尸修改器PvZ Toolkit&#xff1a;新手到高手的5大核心功能全解析 【免费下载链接】pvztoolkit 植物大战僵尸 PC 版综合修改器 项目地址: https://gitcode.com/gh_mirrors/pv/pvztoolkit 植物大战僵尸这款经典游戏陪伴了无数玩家的童年&#xff0c;但你是否想过…...

Android系统开发深度解析:从驱动到优化与物联网应用

引言 在移动操作系统领域,Android凭借其开源性和灵活性,已成为全球主流平台。随着技术发展,Android开发衍生出多个专业角色,包括驱动开发、性能优化、BSP开发和物联网应用开发等。这些职位共同支撑着Android生态系统的稳定性和高效性。本文将从技术角度,系统解析Android驱…...

SAM3效果实测:看看自然语言描述如何实现精准物体提取

SAM3效果实测&#xff1a;看看自然语言描述如何实现精准物体提取 1. 引言&#xff1a;从“画框”到“说话”的进化 过去&#xff0c;如果你想从一张照片里单独抠出某个物体&#xff0c;比如一只猫或者一辆车&#xff0c;通常需要借助专业的图像处理软件&#xff0c;用鼠标小心…...

3步解锁网易云音乐加密歌曲:NCMDump解密全攻略

3步解锁网易云音乐加密歌曲&#xff1a;NCMDump解密全攻略 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的VIP歌曲只能在特定客户端播放而烦恼吗&#xff1f;NCMDump正是为你解决这一困扰的终极工具&#xff…...

2026终极指南:3种方法轻松重置JetBrains IDE试用期

2026终极指南&#xff1a;3种方法轻松重置JetBrains IDE试用期 【免费下载链接】ide-eval-resetter 项目地址: https://gitcode.com/gh_mirrors/id/ide-eval-resetter 还在为JetBrains IDE的30天试用期结束而烦恼吗&#xff1f;ide-eval-resetter是一款专业的IDE评估信…...

Android 14 ShellTransitions 动画参与者收集全解析:从Activity启动到App切换的幕后流程

Android 14 ShellTransitions 动画参与者收集全解析&#xff1a;从Activity启动到App切换的幕后流程 当我们在Android设备上轻触应用图标或按下Home键时&#xff0c;那些流畅的过渡动画背后隐藏着一套精密的参与者收集机制。本文将带您深入Android 14的ShellTransitions系统&am…...

039、FreeRTOS与嵌入式GUI(如LVGL、emWin)的整合:当实时内核遇上图形界面

039、FreeRTOS与嵌入式GUI(如LVGL、emWin)的整合:当实时内核遇上图形界面 最近在调试一个智能家居中控屏项目,遇到了一个典型问题:触摸滑动列表时,界面偶尔会卡顿半秒,同时后台的传感器数据上报也出现了丢包。这种问题在整合RTOS和GUI时太常见了——图形渲染吃掉了大量…...

【2024生成式推荐算法权威基准报告】:12家主流平台Llama-3/Gemini/DeepSeek适配实测数据,仅开放72小时下载权限

第一章&#xff1a;生成式AI应用推荐算法优化 2026奇点智能技术大会(https://ml-summit.org) 生成式AI正深度重构推荐系统的核心范式——从传统协同过滤与矩阵分解&#xff0c;转向以大语言模型&#xff08;LLM&#xff09;和扩散模型为基座的语义理解、意图生成与多模态内容合…...

SITS2026私有化部署最后窗口期:仅剩62天,官方将于5月31日关闭v1.x License续订通道

第一章&#xff1a;智能代码生成技术&#xff1a;SITS2026开发工具专场 2026奇点智能技术大会(https://ml-summit.org) SITS2026 是面向下一代 AI 原生开发范式的集成式智能工具套件&#xff0c;深度融合大语言模型推理引擎与 IDE 行为感知层&#xff0c;支持上下文感知的实时…...

LVGL Spinner控件实战:5分钟搞定3种酷炫加载动画(附ESP32/STM32代码)

LVGL Spinner控件实战&#xff1a;5分钟搞定3种酷炫加载动画&#xff08;附ESP32/STM32代码&#xff09; 在嵌入式GUI开发中&#xff0c;加载动画是提升用户体验的关键细节。LVGL作为轻量级图形库&#xff0c;其Spinner控件能以极低资源消耗实现专业级视觉效果。本文将带你快速…...