OpenCV 图像变换全解析:从镜像翻转到仿射变换的实践指南

前言

        处理图像时,翻转、旋转、平移等操作很常用。OpenCV 提供了简单的方法实现这些变换,本文带你快速学会用它做图像翻转和仿射变换。

1 图像翻转(图像镜像旋转)

在OpenCV中,图片的镜像旋转是以图像的中心为原点进行镜像翻转的。

  • cv2.flip(img,flipcode)

  • 参数

    • img: 要翻转的图像

    • flipcode: 指定翻转类型的标志

      • flipcode=0: 垂直翻转,图片像素点沿x轴翻转

      • flipcode>0: 水平翻转,图片像素点沿y轴翻转

      • flipcode<0: 水平垂直翻转,水平翻转和垂直翻转的结合

示例:

import cv2 as cv
face = cv.imread('../images/face.png')
cv.imshow('face', face)
# 翻转 镜像旋转 以图像中心为原点cv.filp(img, filpcode)
# flipcode = 0垂直翻转 沿x轴 上下翻转
flip_0 = cv.flip(face, 0)
cv.imshow('flip_0', flip_0)
# flipcode = 1垂直翻转 沿y轴 左右翻转
flip_1 = cv.flip(face, 1)
cv.imshow('flip_1', flip_1)
# flipcode = -1垂直+水平翻转
flip = cv.flip(face, -1)
cv.imshow('flip_-1', flip)
cv.waitKey(0)
cv.destroyAllWindows()

结果如下

2 图像仿射变换

        仿射变换(Affine Transformation)是一种线性变换,保持了点之间的相对距离不变。

  • 仿射变换的基本性质

    • 保持直线

    • 保持平行

    • 比例不变性

    • 不保持角度和长度

  • 常见的仿射变换类型

    • 旋转:绕着某个点或轴旋转一定角度。

    • 平移:仅改变物体的位置,不改变其形状和大小。

    • 缩放:改变物体的大小。

    • 剪切:使物体发生倾斜变形。

  • 仿射变换的基本原理

    • 线性变换

    • 二维空间中,图像点坐标为(x,y),仿射变换的目标是将这些点映射到新的位置 (x', y')。

    • 为了实现这种映射,通常会使用一个矩阵乘法的形式:

      (类似于y=kx+b)

      • a,b,c,d 是线性变换部分的系数,控制旋转、缩放和剪切。

      • t_x,t_y 是平移部分的系数,控制图像在平面上的移动。

      • 输入点的坐标被扩展为齐次坐标形式[x,y,1],以便能够同时处理线性变换和平移

  • cv2.warpAffine()函数

    • 仿射变换函数

      cv2.warpAffine(img,M,dsize)
      • img:输入图像。

      • M:2x3的变换矩阵,类型为np.float32

      • dsize:输出图像的尺寸,形式为(width,height)

2.1 图像旋转

        旋转图像可以将图像绕着某个点旋转一定的角度。

cv2.getRotationMatrix2D()函数

  • 获取旋转矩阵

    cv2.getRotationMatrix2D(center,angle,scale)
    • center:旋转中心点的坐标,格式为(x,y)

    • angle:旋转角度,单位为度,正值表示逆时针旋转负值表示顺时针旋转。

    • scale:缩放比例,若设为1,则不缩放。

    • 返回值M,2x3的旋转矩阵。

示例:

import cv2
import cv2 as cv
# 读图
pig = cv.imread('../images/pig.png')
pig = cv.resize(pig, (520,520))
# 获取旋转矩阵 cv2.getRotationMatrix2D(center,angle,scale)
M = cv2.getRotationMatrix2D((260, 260), -45, 1)
# 仿射变换函数cv.warpAffine(img,M,(w,h)
dst = cv.warpAffine(pig, M, (pig.shape[1], pig.shape[0]))
cv.imshow('pig', pig)
cv.imshow('pig_new', dst)
cv.waitKey(0)
cv.destroyAllWindows()

2.2 图像平移

移操作可以将图像中的每个点沿着某个方向移动一定的距离。

  • 假设我们有一个点 P(x,y),希望将其沿x轴方向平移t_x*个单位,沿y轴方向平移t_y个单位到新的位置P′(x′,y′),那么平移公式如下:

    x′=x+tx

    y′=y+ty

    在矩阵形式下,该变换可以表示为:

        这里的t_x和t_y分别代表在x轴和y轴上的平移量。

示例:

import cv2
import cv2 as cv
import numpy as np# 读图
pig = cv.imread('../images/pig.png')
pig = cv.resize(pig, (520,520))
# 定义偏移量
tx = 80
ty = 120
# 定义平移矩阵
M = np.float32([[1, 0, tx], [0, 1, ty]])
# 仿射变换矩阵,找不到的就用黑色填充
dst = cv.warpAffine(pig, M, (520, 520))
cv.imshow('pig', pig)
cv.imshow('pig_new', dst)
cv.waitKey(0)
cv.destroyAllWindows()

2.3 图像缩放

缩放操作可以改变图片的大小。

  • 假设要把图像的宽高分别缩放为0.5和0.8,那么对应的缩放因子sx=0.5,sy=0.8。

  • 点P(x,y)对应到新的位置P'(x',y'),缩放公式为:

    x′=sx*x

    y′=sy*y

    在矩阵形式下,该变换可以表示为:

    相较于图像旋转中只能等比例的缩放,图像缩放更加灵活,可以在指定方向上进行缩放。

sx和sy分别表示在x轴和y轴方向上的缩放因子。

示例:

import cv2 as cv
import numpy as np# 读图
pig = cv.imread('../images/pig.png')
pig = cv.resize(pig, (520,520))
# 定义缩放移量
sx = 0.6
sy = 0.5
# 定义缩放矩阵
M = np.float32([[sx, 0, 0], [0, sy, 0]])
# 仿射变换矩阵,找不到的就用黑色填充
dst = cv.warpAffine(pig, M, (520, 520))
cv.imshow('pig', pig)
cv.imshow('pig_new', dst)
cv.waitKey(0)
cv.destroyAllWindows()

2.4 图像剪切(了解即可)

剪切操作可以改变图形的形状,以便其在某个方向上倾斜,它将对象的形状改变为斜边平行四边形,而不改变其面积

  • 想象我们手上有一张矩形纸片,如果你固定纸片的一边,并沿着另一边施加一个平行于该边的力,这张纸片就会变形为一个平行四边形。这就是剪切变换的一个直观解释。

  • 对于二维空间中的点P(x,y),对他进行剪切变换:

    沿x轴剪切:x'=x+shy*y       y'=y

    沿y轴剪切:x'=x       y'=shx*x+y

  • 当需要同时沿两个方向进行剪切时,x'=x+shy*y , y'=shx*x+y

  • 在矩阵形式下,该变换可以表示为:

  • 来一个图理解一下:

shy和shx分别对应沿x轴和y轴方向上的剪切因子。

  • 可以理解为,x不变,y偏移

总结:

        本文讲了 OpenCV 的两种图像变换。用cv.flip()能轻松实现图像的垂直、水平翻转。仿射变换里,通过矩阵设置,结合cv.warpAffine()可完成旋转、平移、缩放和剪切。这些基础操作是图像处理的必备技能,多练就能熟练掌握。

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

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

相关文章

【运维】Linux运维命令记录

重置root密码使用命令重新设置一下root账户的密码 passwd root根据提示设置一下密码&#xff0c;然后使用sudo -i 时输入密码就可以切换到root账户了ssh登陆以后&#xff0c;要用sudo -i命令给用户提权&#xff0c;提到超级管理员&#xff0c;然后输入密码才有用

PandasAI连接LLM进行智能数据分析

1. 引言 Pandas是一个数据分析开源组件库&#xff0c;提供了高性能、易用的数据结构和数据分析工具。它的核心的功能是其DataFrame对象&#xff0c;这是一个带有行和列标签的二维表格数据结构&#xff0c;支持缺失数据处理、时间序列功能、灵活的数据输入输出方法、数据对齐和…

Spring之【Bean的生命周期】

目录 1、生成BeanDefinition BeanDefinitionRegistry接口 DefaultListableBeanFactory实现类 2、合并BeanDefnition AbstractBeanFactory类 3、BeanFactoryPostProcessor的方法回调 AbstractApplicationContext类 PostProcessorRegistrationDelegate类 4、BeanPostPro…

搜狐新闻直播间适配HarmonyOs实现点赞动画

01背景介绍随着新闻客户端鸿蒙单框架系统适配工作的推进&#xff0c;从原来的基础功能到现在已经适配全功能的85%以上。与此同时&#xff0c;我们也在持续深入挖掘鸿蒙系统的特性&#xff0c;以提升整体应用的质量与用户体验。在这一过程中&#xff0c;动画作为增强交互与视觉体…

83、设置有人DTU设备USR-M100采集传感器数据,然后上传阿里云服务

基本思想:设置M100 采集传感器数据 一、首先将DTU设备USR-M100连接路由器上,然后使用python代码搜索同一局域网设备, import platform import sys import os import time import threadinglive_ip = 0def get_os():os = platform.system()if os == "Windows":re…

P1019 [NOIP 2000 提高组] 单词接龙

题目描述单词接龙是一个与我们经常玩的成语接龙相类似的游戏&#xff0c;现在我们已知一组单词&#xff0c;且给定一个开头的字母&#xff0c;要求出以这个字母开头的最长的“龙”&#xff08;每个单词都最多在“龙”中出现两次&#xff09;&#xff0c;在两个单词相连时&#…

详解力扣高频SQL50题之1633. 各赛事的用户注册率【简单】

传送门&#xff1a;1633. 各赛事的用户注册率 题目 用户表&#xff1a; Users -------------------- | Column Name | Type | -------------------- | user_id | int | | user_name | varchar | -------------------- user_id 是该表的主键(具有唯一值的列)。 该表中的每行包…

FROM stakater/java8-alpine 构建cocker镜像

在 Dockerfile 中&#xff0c;FROM stakater/java8-alpine 是第一条也是最核心的指令&#xff0c;它定义了构建新镜像所基于的「基础镜像」。以下是逐层解析&#xff1a;&#x1f50d; 关键字拆解 1. FROM —— 起点指令 ✅ 作用&#xff1a;声明当前镜像的起点&#xff08;父镜…

Word2Vec模型训练全流程解析:从数据预处理到实体识别应用

请添加图片描述 训练Word2Vec模型 概述 问题 我们如何训练Word2Vec模型&#xff1f;在特定数据集上训练Word2Vec模型何时是有利的&#xff1f; 目标 理解在自有数据上训练Word2Vec模型而非使用预训练模型的优势 Colab环境配置 运行以下代码以启用辅助函数并重新读取数据…

在Ubuntu上使用QEMU学习RISC-V程序(2)gdb调试

文章目录一、准备工作二、基本调试流程1. 设置断点2. 执行程序3. 查看源代码/汇编三、查看寄存器1. 查看通用寄存器2. 查看特殊寄存器四、查看内存1. 内存查看命令2. 内存修改命令五、调试实战示例六、高级调试技巧1. 条件断点2. 自动显示3. 内存断点&#xff08;观察点&#x…

不止于“亮”:一盏智慧路灯的技术进化史——塔能科技用“落地性”定义行业标准

在凌晨3点的园区道路之上&#xff0c;路灯会随着车辆的靠近而自动亮起&#xff0c;待车辆逐渐远去之后&#xff0c;又会缓缓地调暗下来&#xff1b;当电缆意外被触碰的时候&#xff0c;系统能够在短短3秒之内自动发出报警信息&#xff0c;并且推送出维修工单&#xff1b;而当一…

Redis的String数据类型底层实现

redis就是用c语言写&#xff0c;但redis的string并没有直接用c语言的string&#xff0c;而是自己搞了一个 SDS 结构体来表示字符串。SDS 的全称是 Simple Dynamic String&#xff0c;中文叫做“简单动态字符串”。想知道为什么这么做&#xff0c;我们先看看c语言的string是什么…

【音视频学习】四、深入解析视频技术中的YUV数据存储方式:从原理到实践

文章目录 引言 1. YUV 基础:为什么它比 RGB 更适合视频? 1.1 YUV 与 RGB 的核心区别 1.2 YUV色度下采样简介 2. YUV 的三大存储方式 方式一:平面格式(Planar) 方式二:半平面格式(Semi-Planar ) 方式三:打包格式(Packed YUV) 三种存储方式对比: 3. 如何选择合适的 Y…

前端项目组成

一、前端项目常见模块及功能&#xff08;以 Vue/React 通用结构为例&#xff09; 前端项目的模块本质是「按功能拆分的代码文件/文件夹」&#xff0c;就像盖房子的「砖、梁、窗」各司其职&#xff1a;模块类型功能说明&#xff08;大白话&#xff09;举个例子pages&#xff08;…

聚观早报 | 猿编程推动中美青少年AI实践;华为Pura 80数字版售价公布;iPhone 17 Air电池曝光

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。整理丨肖羽7月24日消息猿编程推动中美青少年AI实践华为Pura 80数字版售价公布iPhone 17 Air电池曝光亚马逊收购AI初创公司Bee蜂巢半固…

unittest 案例执行顺序详解

unittest 案例执行顺序详解在 unittest 框架中&#xff0c;测试用例的执行顺序有默认规则&#xff0c;也可通过自定义方式调整。以下是具体说明&#xff1a;一、默认执行顺序规则unittest 对测试用例的执行顺序遵循 “按测试方法名的 ASCII 码排序” 原则&#xff0c;具体逻辑如…

【web大前端】001_前端开发入门:创建你的第一个网页

前端开发入门&#xff1a;创建你的第一个网页 在当今数字化时代&#xff0c;网页已经成为人们获取信息和交流的重要平台。对于想要学习编程的人来说&#xff0c;前端开发往往是一个不错的起点。本文将带你通过简单的两步&#xff0c;创建属于你的第一个网页程序。 点击这里去…

HTTP性能优化终极指南:从协议原理到企业级实践

前言&#xff1a;为什么性能优化是Web开发的生命线&#xff1f;根据Google研究数据&#xff0c;当页面加载时间从1秒增加到3秒时&#xff0c;跳出率提升32%&#xff1b;当达到5秒时&#xff0c;转化率下降90%。本文将通过七层优化体系&#xff0c;带您掌握HTTP性能优化的核心技…

Python 数据分析(二):Matplotlib 绘图

目录 1. 简介2. 绘图 2.1 折线图 2.1.1 单线2.1.2 多线2.1.3 子图 2.2 散点图2.3 直方图2.4 条形图 2.4.1 纵置2.4.2 横置2.4.3 多条 2.5 饼图 1. 简介 Matplotlib 是 Python 提供的一个绘图库&#xff0c;通过该库我们可以很容易的绘制出折线图、直方图、散点图、饼图等丰…

Scrapy分布式爬虫数据统计全栈方案:构建企业级监控分析系统

引言&#xff1a;数据统计在分布式爬虫中的战略价值在分布式爬虫系统中&#xff0c;​​数据统计与分析​​是系统优化的核心驱动力。根据2023年爬虫工程调查报告&#xff1a;实施专业统计方案的爬虫系统性能提升​​40%以上​​数据驱动的优化策略可减少​​70%​​的资源浪费…