【计算机视觉】图像的几何变换

news2025/1/19 8:22:50

最常见的几何变换有仿射变换和单应性变换两种,最常用的仿射变换有缩放、翻转、旋转、平移。

1. 缩放

将图像放大或缩小会得到新的图像,但是多出的像素点如何实现----插值

1.1 插值方法

最近邻插值
双线性插值
cv2.resize() 是 OpenCV 中用于调整图像大小的函数。它可以将图像缩放到指定尺寸,或按照比例进行缩放,是图像处理任务中非常常用的功能之一。

cv2.resize(src, dsize, dst=None, fx=0, fy=0, interpolation=cv2.INTER_LINEAR)
参数详解
  1. src (必选):

    • 输入图像,数据类型为 NumPy 数组。
    • 形状可以是灰度图 (H x W) 或彩色图 (H x W x C)。
  2. dsize (必选):

    • 输出图像的目标尺寸,格式为 (width, height)
    • 如果提供了 dsize,则会忽略 fxfy 参数。
  3. dst (可选):

    • 输出图像(默认为 None)。
    • 通常不使用这个参数,返回值即为调整后的图像。
  4. fxfy (可选):

    • 分别表示图像在宽度方向 (x) 和高度方向 (y) 的缩放因子。
    • 如果设置了 fxfy,会按照比例缩放图像,忽略 dsize
  5. interpolation (可选):

    • 插值方法,用于在缩放过程中生成新像素值。常见选项有:
      • cv2.INTER_NEAREST: 最近邻插值,速度快,质量较差。
      • cv2.INTER_LINEAR: 双线性插值(默认),适用于缩小图像。
      • cv2.INTER_CUBIC: 双三次插值,适用于放大图像,质量较高但速度较慢。
      • cv2.INTER_LANCZOS4: Lanczos 插值,适用于高质量缩放。
      • cv2.INTER_AREA: 使用像素区域关系插值,适用于缩小图像,效果较好。
返回值
  • 返回调整大小后的图像,数据类型与输入图像相同。

2. 翻转、旋转和平移

2.1 翻转

图像的翻转是指以某条线为轴进行翻转图像得到一副新的图像,新的图像与原始图像关于翻转轴对称。
cv2.flip() 是 OpenCV 提供的一个图像翻转函数,用于按照指定的轴对图像进行镜像翻转操作。通过这个函数,可以实现水平翻转、垂直翻转或同时进行水平和垂直翻转。

cv2.flip(src, flipCode)
参数详解
  1. src (必选):

    • 输入图像,数据类型为 NumPy 数组。
    • 可以是灰度图(H x W)或彩色图(H x W x C)。
  2. flipCode (必选):

    • 控制图像的翻转方向,值的取值意义如下:
      • 0: 沿 x 轴(垂直翻转) 翻转。
      • 1: 沿 y 轴(水平翻转) 翻转。
      • -1: 同时沿 x 轴和 y 轴(中心对称翻转) 翻转。
返回值
  • 返回翻转后的图像,数据类型和形状与输入图像一致。

2.2 旋转

图像的旋转是指以某一点为旋转中心旋转图像得到一副新的图像。

2.3 平移

图像的平移是指图像沿着平面内的某一方向移动一定距离得到一副新的图像。

3. 仿射变换

图像的仿射变换是将图像进行一系列的线性变换(缩放、旋转、错切)和平移变换得到新图像的操作;新图像保留了原始图像点的共线性以及线之间的平行线、线段间的长度比
cv2.warpAffine() 是 OpenCV 中用于对图像进行仿射变换的函数,可以实现平移、旋转、缩放等操作。以下是函数的详解。

cv2.warpAffine(src, M, dsize, dst=None, flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=0)
参数详解
  1. src
    输入图像,通常是一个二维灰度图或三维彩色图像(numpy.ndarray 格式)。

  2. M
    仿射变换矩阵(2x3 矩阵)。这是图像变换的核心参数,定义了如何操作图像的像素点位置。

    • 仿射变换可以表示为:
      在这里插入图片描述
  3. dsize
    输出图像的尺寸,格式为 (width, height)

    • 决定了输出图像的大小。
  4. dst (可选)
    输出的目标图像,通常省略。

  5. flags
    插值方法,用于计算目标像素值。常见选项:

    • cv2.INTER_NEAREST:最近邻插值(速度最快,质量较低)。
    • cv2.INTER_LINEAR:双线性插值(默认,平衡速度和质量)。
    • cv2.INTER_CUBIC:三次插值(质量较高,但速度慢)。
    • cv2.INTER_LANCZOS4:Lanczos 插值(用于缩小图像时效果最好)。
  6. borderMode (可选)
    定义边界像素的处理方式。常见选项:

    • cv2.BORDER_CONSTANT:填充常量值(默认)。
    • cv2.BORDER_REPLICATE:复制边缘像素。
    • cv2.BORDER_REFLECT:反射边界。
  7. borderValue (可选)
    borderModecv2.BORDER_CONSTANT 时,定义填充边界的值。默认是 0,即黑色。

实例代码

以下是使用 cv2.warpAffine 函数实现平移、旋转和缩放操作的 Python 代码示例。我们将通过设置不同的仿射变换矩阵实现这些操作。

完整代码示例
import cv2
import numpy as np

# 读取图像
image = cv2.imread("example.jpg")
(h, w) = image.shape[:2]

# 显示原始图像
cv2.imshow("Original Image", image)

# --- 平移操作 ---
# 平移矩阵: 将图像向右平移 50 像素,向下平移 30 像素
tx, ty = 50, 30
translation_matrix = np.array([[1, 0, tx], [0, 1, ty]], dtype=np.float32)

# 使用 warpAffine 应用平移
translated_image = cv2.warpAffine(image, translation_matrix, (w, h))
cv2.imshow("Translated Image", translated_image)

# --- 旋转操作 ---
# 定义旋转中心、角度和缩放比例
center = (w // 2, h // 2)
angle = 45  # 顺时针旋转 45 度
scale = 1.0

# 生成旋转矩阵
rotation_matrix = cv2.getRotationMatrix2D(center, angle, scale)

# 使用 warpAffine 应用旋转
rotated_image = cv2.warpAffine(image, rotation_matrix, (w, h))
cv2.imshow("Rotated Image", rotated_image)

# --- 缩放操作 ---
# 缩放矩阵: 将图像横向和纵向分别缩放到原来的 1.5 倍
sx, sy = 1.5, 1.5
scaling_matrix = np.array([[sx, 0, 0], [0, sy, 0]], dtype=np.float32)

# 计算缩放后的尺寸
scaled_width = int(w * sx)
scaled_height = int(h * sy)

# 使用 warpAffine 应用缩放
scaled_image = cv2.warpAffine(image, scaling_matrix, (scaled_width, scaled_height))
cv2.imshow("Scaled Image", scaled_image)

# --- 组合操作: 平移 + 旋转 + 缩放 ---
# 创建一个综合仿射变换矩阵
combined_matrix = np.dot(rotation_matrix, scaling_matrix)
combined_matrix[:, 2] += np.array([tx, ty])  # 加入平移分量

# 计算最终图像尺寸
new_width = int(scaled_width)
new_height = int(scaled_height)

# 应用综合仿射变换
combined_image = cv2.warpAffine(image, combined_matrix, (new_width, new_height))
cv2.imshow("Combined Transformation Image", combined_image)

# 等待按键并释放窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
代码说明
  1. 平移操作
    仿射变换矩阵:
    M translation = [ 1 0 t x 0 1 t y ] M_{\text{translation}} = \begin{bmatrix} 1 & 0 & t_x \\ 0 & 1 & t_y \end{bmatrix} Mtranslation=[1001txty]
    将图像在 x 和 y 方向上分别平移 t_xt_y 个像素。

  2. 旋转操作
    使用 cv2.getRotationMatrix2D 生成旋转矩阵,旋转角度和中心点可以自定义。

  3. 缩放操作
    仿射变换矩阵:
    M scaling = [ s x 0 0 0 s y 0 ] M_{\text{scaling}} = \begin{bmatrix} s_x & 0 & 0 \\ 0 & s_y & 0 \end{bmatrix} Mscaling=[sx00sy00]
    s_xs_y 分别是 x 和 y 方向上的缩放比例。

  4. 组合操作

    • 通过矩阵乘法 (np.dot) 将多个变换矩阵合并。
    • 调整矩阵偏移量(第 3 列)以同时实现平移。
运行结果
  • Translated Image:图像被平移。
  • Rotated Image:图像被旋转。
  • Scaled Image:图像被缩放。
  • Combined Transformation Image:图像被平移、旋转和缩放的组合效果。

4. 单应性变换

图像的仿射变换保留了原始图像点的共线性以及线之间的平行线、线段间的长度比;但是单应性变换,只保留了共线性。广泛应用于图像校正、全景拼接、图像配准、机器人导航、增强现实领域。
cv2.findHomography 是 OpenCV 中用于计算 单应性矩阵(Homography Matrix)的函数,常用于图像配准(Image Registration)、透视变换(Perspective Transformation)等场景。它可以通过一组点对应关系计算出两幅图像之间的几何变换。

retval, H = cv2.findHomography(srcPoints, dstPoints, method=cv2.RANSAC, ransacReprojThreshold=3.0, mask=None, maxIters=2000, confidence=0.995)
参数详解
  1. srcPoints

    • 类型:numpy.ndarray 或 类似的可迭代对象,形状为 (N \times 2) 或 (N \times 1 \times 2)。
    • 描述:源点集合(图像1中的点坐标)。
      这些点是已知的特征点,用于计算单应性矩阵。
  2. dstPoints

    • 类型:与 srcPoints 相同。
    • 描述:目标点集合(图像2中的点坐标)。
      每个源点在目标图像中的对应点。
  3. method (可选)

    • 类型:整数(用于指定计算方法)。
    • 描述:选择计算单应性矩阵的方法。
      • cv2.RANSAC(默认):使用随机抽样一致性算法(RANSAC),可排除异常点。
      • cv2.LMEDS:最小中值算法(Least Median of Squares),对异常值更鲁棒。
      • cv2.RHO:一种优化方法,适合数据分布较好的情况。
  4. ransacReprojThreshold (仅当使用 RANSAC 方法时生效)

    • 类型:浮点数。
    • 描述:RANSAC 中的重投影误差阈值(以像素为单位)。小于此值的点被视为内点。
  5. mask (可选)

    • 类型:布尔掩码,numpy.ndarray
    • 描述:用于标记内点和外点的输出掩码。
      • 内点(符合几何关系的点)标记为 1
      • 外点(不符合几何关系的点)标记为 0
  6. maxIters (仅在 RANSAC 方法中可用)

    • 类型:整数。
    • 描述:RANSAC 最大迭代次数。
  7. confidence (仅在 RANSAC 方法中可用)

    • 类型:浮点数,范围为 [0, 1]
    • 描述:单应性矩阵估计的置信度。

返回值
  1. retval

    • 类型:布尔值。
    • 描述:计算是否成功。
  2. H

    • 类型:3x3 单应性矩阵。
    • 描述:定义了两个平面之间的透视关系,表示从源图像到目标图像的映射。
      在这里插入图片描述
示例 1:计算单应性矩阵
import cv2
import numpy as np

# 定义源点和目标点
src_points = np.array([[10, 10], [200, 10], [200, 200], [10, 200]], dtype=np.float32)
dst_points = np.array([[20, 30], [220, 50], [210, 220], [30, 230]], dtype=np.float32)

# 计算单应性矩阵
H, mask = cv2.findHomography(src_points, dst_points, method=cv2.RANSAC)

print("Homography Matrix:")
print(H)
print("Mask of inliers:")
print(mask)
示例 2:图像透视变换
import cv2
import numpy as np

# 读取图像
image = cv2.imread("example.jpg")
(h, w) = image.shape[:2]

# 定义源点和目标点
src_points = np.array([[100, 100], [400, 100], [400, 400], [100, 400]], dtype=np.float32)
dst_points = np.array([[50, 150], [450, 100], [400, 450], [100, 400]], dtype=np.float32)

# 计算单应性矩阵
H, _ = cv2.findHomography(src_points, dst_points)

# 应用透视变换
warped_image = cv2.warpPerspective(image, H, (w, h))

# 显示结果
cv2.imshow("Original Image", image)
cv2.imshow("Warped Image", warped_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

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

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

相关文章

深入浅出 Go 语言:数组与切片

深入浅出 Go 语言:数组与切片 引言 在 Go 语言中,数组和切片是两种非常重要的数据结构,用于存储和操作一组相同类型的元素。虽然它们看起来相似,但在使用上有很大的区别。理解数组和切片的区别以及如何正确使用它们,…

基于超级电容和电池的新能源汽车能量管理系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 超级电容特性 4.2 电池特性 5.完整工程文件 1.课题概述 基于超级电容和电池的新能源汽车能量管理系统simulink建模与仿真。分析不同车速对应的电池,超级电容充放电变化情况。 2.系统仿…

y3编辑器文档3:物体编辑器

文章目录 一、物体编辑器简介1.1 界面介绍1.2 复用(导入导出)1.3 收藏夹(项目资源管理)1.4 对象池二、单位2.1 数据设置2.2 表现设置2.3 单位势力和掉率设置2.4 技能添加和技能参数修改2.5 商店2.5.1 商店属性设置2.5.2 商店物品设置三、装饰物3.1 属性编辑3.2 碰撞体积四、…

「嵌入式系统设计与实现」书评:学习一个STM32的案例

本文最早发表于电子发烧友论坛:【新提醒】【「嵌入式系统设计与实现」阅读体验】 学习一个STM32的案例 - 发烧友官方/活动 - 电子技术论坛 - 广受欢迎的专业电子论坛!https://bbs.elecfans.com/jishu_2467617_1_1.html 感谢电子发烧友论坛和电子工业出版社的赠书。 …

Qt Designer Ui设计 功能增加

效果展示 输入密码,密码错误,弹出提示 密码正确,弹出提示并且关闭原窗口 代码(只提供重要关键主代码)lxh_log.py代码: import sysfrom PySide6.QtWidgets import QApplication, QWidget, QPushButtonfrom …

RT Thread Studio新建STM32F407IG工程文件编译提示错误

编译提示错误 原因: RT 源码使用4.0.3的话,请用STM32F4支持包的0.2.2版本,就不会出错了。 如果支持包用0.2.3版本的话,需要用RT内核4.1.0版本。0.2.3 版本更新了一些针对内核4.1.0的驱动代码,这几个定义都是4.1.0里的。

智能制造标准体系建设指南

一、智能制造系统架构总览 智能制造作为当今制造业转型升级的核心,深度整合了新一代信息技术与传统制造工艺,催生出一个横跨产品全生命周期、纵贯多层级组织架构,并彰显多元智能特性的复杂系统。这一架构从生命周期、系统层级、智能特征三个…

DApp开发与APP开发的五大区别

随着比特币与区块链技术的不断发展,DApp应用会逐渐成为主流。与APPAPP相比,DApp有许多不同之处,尤其是在架构、数据存储、用户隐私等方面。本文将通过五大关键点,深入探讨DApp开发与APP开发之间的主要区别。 1. 后端架构&#xff…

XSS(DOM)-HIGH错误总结

HIGH就不从简单的开始。 我们直接闭合HTML标签绕过 ></option></select><img srcx:alert(alt) οnerrοreval(src) altxss> 没有变化 这里应该是后端的问题&#xff0c;试试锚点注入 English#<script>alert(xss)</script> 这里不知道什么…

Mitel MiCollab 企业协作平台 任意文件读取漏洞复现(CVE-2024-41713)

0x01 产品简介 Mitel MiCollab是加拿大Mitel(敏迪)公司推出的一款企业级协作平台,旨在为企业提供统一、高效、安全的通信与协作解决方案。通过该平台,员工可以在任何时间、任何地点,使用任何设备,实现即时通信、语音通话、视频会议、文件共享等功能,从而提升工作效率和…

【PostgreSQL系列】列类型从整数转换为 UUID

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【原生js案例】webApp实现鼠标移入移出相册放大缩小动画

图片相册这种动画效果也很常见&#xff0c;在我们的网站上。鼠标滑入放大图片&#xff0c;滑出就恢复原来的大小。现在我们使用运动定时器来实现这种滑动效果。 感兴趣的可以关注下我的系列课程【webApp之h5端实战】&#xff0c;里面有大量的css3动画效果制作原生知识分析&…

Java项目实战II基于微信小程序的消防隐患在线举报系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着城市化进程的加快&…

饲料颗粒机全套设备有哪些机器组成

颗粒饲料机主要用于将各种饲料原料&#xff08;如玉米、豆粕、麦麸、鱼粉等&#xff09;进行混合、压制&#xff0c;制成颗粒状的饲料。这种饲料不仅方便储存和运输&#xff0c;还能提高动物的采食效率和饲料利用率。同时&#xff0c;颗粒饲料在加工过程中能灭部分微生物和寄生…

Free-RTOS实现LED闪烁

开发板&#xff1a;正点原子探索者 F407 LED定时定时闪烁 本次实验验证&#xff1a; 配置文件 1、打开CubeMX 2、选择芯片型号&#xff0c;然后点击开始项目 3、配置时钟 配置烧录引脚&#xff0c;与FreeRTOS系统时钟 选择FreeRTOS 这里已经默认有一个任务&#xff…

【书生大模型实战营】Linux 基础知识-L0G1000

前言&#xff1a;书生大模型实战营是上海人工智能实验室开展的大模型系列实践活动&#xff0c;提供免费算力平台&#xff0c;学员通过闯关式任务&#xff0c;可获得免费算力和存储&#xff0c;助力项目实践。本期是第4期&#xff0c;时间从十一月份开始&#xff0c;持续到十二月…

Python实现Excel中数据条显示

Python中要实现百分比数据条的显示&#xff0c;可以使用pandas库&#xff0c;pandas图表样式的设置与Excel中的条件格式设置比较类似&#xff0c;比如Excel里常用的数据条的用法&#xff0c;在pandas中使用代码进行高亮显示&#xff0c;用来突出重点数据&#xff0c;下面一起来…

R语言机器学习论文(三):特征提取

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载导入数据一、数据归一化二、离散型分类变量的编码三、筛选特征四、重要特征五、输出结果六、总结系统信息介绍 在数据分析和机器学习项目中,经常需要对数据进行预…

Java 初学者的第一个 SpringBoot 登录系统

Java 初学者的第一个 SpringBoot 登录系统 对编程初学者而言&#xff0c;都存在一个 “第一个系统” 的问题。有些学习者找不到自己的 “第一个系统”&#xff0c;他们即使再努力也没有办法了解完整的系统&#xff0c;即使他们把教科书里的所有程序都跑通了。但是&#xff0c;…