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

【opencv-Python学习笔记(5):几何变换】

目标

1. 熟练掌握图像的几何变换,缩放、翻转、仿射等等


几何变换原理说明:几何变换的本质是像素坐标的映射:通过数学公式将原始图像的像素坐标 (x, y) 映射到新图像的坐标 (x', y'),并根据插值算法确定新像素的值。

1.图像缩放

解释:调整图像的尺寸大小,可按比例或指定尺寸缩放。

函数:cv2.resize(src, dsize, fx=0, fy=0, interpolation=...)

参数:

  • src:输入图像
  • dsize:输出尺寸 (width, height)
  • fx/fy:宽 / 高的缩放因子(若指定,dsize 可设为 None
  • interpolation:插值方法(影响缩放质量)

插值方法选择(常用)

  • 缩小图像:cv2.INTER_AREA(推荐,抗锯齿)
  • 放大图像:cv2.INTER_CUBIC(高质量,慢)或 cv2.INTER_LINEAR(较快)

说明:缩放的方式有两种,一是按照直接设置dsize的值,二是设置fx,fy的值

import cv2img = cv2.imread('image.jpg')# 方法1:指定输出尺寸 (宽, 高)
resized1 = cv2.resize(img, (400, 300))  # 宽400,高300# 方法2:按缩放因子(0.5倍缩小)
resized2 = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)

2. 图像翻转(Flip)

解释:沿水平、垂直或对角线翻转图像。

函数cv2.flip(src, flipCode)

  • flipCode = 0:沿 x 轴翻转(垂直翻转)
  • flipCode > 0:沿 y 轴翻转(水平翻转),数值随便给,1,2,3都行
  • flipCode < 0:同时沿 x 轴和 y 轴翻转(对角翻转),数值随便给-1,-2,-3


3. 仿射变换

解释:仿射变换(Affine Transformation) 是一种保持图像 “平行性” 和 “比例性” 的几何变换,它能够将直线映射为直线,将平行线映射为平行线,但可能改变图形的角度和距离。这种变换可以理解为平移、旋转、缩放、剪切等基本变换的组合。

仿射变换实现步骤:

  1. 计算变换矩阵

    使用 cv2.getAffineTransform(srcPoints, dstPoints) 函数,通过3 对对应点(源图像 3 个点→目标图像 3 个点)计算变换矩阵。3 对 points 不能共线,否则矩阵无法唯一确定。

  2. 应用变换矩阵

    使用 cv2.warpAffine(src, M, dsize) 函数,将变换矩阵应用到图像上。


## 变换矩阵函数: cv2.getAffineTransform(srcPoints, dstPoints)

解释说明:该函数用于通过3 对对应点(源图像点→目标图像点)计算仿射变换矩阵(2×3 矩阵),是仿射变换的 “核心计算工具”。

参数详解:

srcPoints

  • 类型:numpy.ndarray(必须是 32 位浮点数类型 np.float32
  • 形状:(3, 2) 或 (1, 3, 2)(3 个点,每个点含 x、y 坐标)
  • 含义:源图像中用于计算变换的 3 个非共线点(若共线,矩阵无法唯一确定,会报错)。
  • 示例:np.float32([[x1,y1], [x2,y2], [x3,y3]])

dstPoints

  • 类型:numpy.ndarray(同 srcPoints,需为 np.float32
  • 形状:与 srcPoints 一致((3, 2) 或 (1, 3, 2)
  • 含义:目标图像中与 srcPoints 一一对应的 3 个点,定义了源点经过仿射变换后应到达的位置。
  • 示例:np.float32([[x1',y1'], [x2',y2'], [x3',y3']])

## 仿射函数: cv2.warpAffine(src, M, dslags)

参数解释:

  • src:类型:numpy.ndarray(图像矩阵),输入的原始图像(可以是单通道灰度图或多通道彩色图)。
  • M:仿射变换矩阵,定义了像素坐标的映射规则。类型为numpy.ndarray,2×3 的矩阵(必须是 cv2.getAffineTransform() 的返回值或符合格式的自定义矩阵
  • dsize:输出图像的尺寸大小(宽 × 高),需根据变换后的图像范围设置,避免内容被截断
  • 类型为元组 (width, height),示例:(600, 400) 表示输出图像宽 600 像素,高 400 像素。
  • flags:表示差值的方法,自己去查,不想写了

例子:

import cv2
import numpy as np# 读取图像
img = cv2.imread('image.jpg')
h, w = img.shape[:2]# 1. 定义3对对应点(源点→目标点)
src = np.float32([[50, 50], [200, 50], [50, 200]])  # 源图像中的三角形顶点
dst = np.float32([[100, 100], [250, 80], [120, 220]])  # 目标图像中的对应顶点# 2. 计算仿射矩阵
M = cv2.getAffineTransform(src, dst)# 3. 应用仿射变换(设置输出尺寸、插值方法、边界填充)
result = cv2.warpAffine(src=img,M=M,dsize=(w + 100, h + 100),  # 扩大输出尺寸避免截断flags=cv2.INTER_CUBIC,     # 高质量插值borderMode=cv2.BORDER_CONSTANT,  # 固定值填充borderValue=(255, 255, 255)  # 白色填充边缘
)cv2.imshow('Result', result)
cv2.waitKey(0)

4. 图像旋转

说明:其实缩放、翻转、旋转等等都属于仿射变换的一种旋转通常以图像中心自定义点为中心

旋转步骤:

1. 获得旋转矩阵

函数:cv2.getRotationMatrix2D(center, angle, scale)

作用该函数用于计算旋转所需的2×3 仿射变换矩阵,是旋转操作的核心。

参数:

  • center:旋转中心坐标,类型:元组 (cx, cy),示例:(w//2, h//2) 表示以图像中心为旋转中心(w 为宽,h 为高)。
  • angle:旋转角度,正值为逆时针旋转。负值,顺时针旋转。示例:30 表示逆时针旋转 30 度,-45 表示顺时针旋转 45 度。
  • scale:旋转后图像的缩放因子。1.0:不缩放(默认);>1.0:放大(如 1.2 表示放大 1.2 倍);<1.0:缩小(如 0.8 表示缩小到 80%)。

2. 执行旋转操作

函数:cv2.warpAffine(src, M, dsize[, flags[, borderMode[, borderValue]]])

说明:该函数通过旋转矩阵 M 对图像执行旋转,与仿射变换共用(旋转本质是特殊的仿射变换)

参数:

  • src:输入图像(numpy 数组,支持单通道或多通道)。
  • Mcv2.getRotationMatrix2D() 生成的 2×3 旋转矩阵。
  • dsize:输出图像尺寸,元组 (width, height)
    • 若旋转后图像可能超出原尺寸(如旋转非 90° 倍数的角度),需设置更大的 dsize 避免内容被截断(计算方法见下文示例)。
  • flags:插值方法(影响旋转后图像的清晰度):
    • cv2.INTER_LINEAR:双线性插值(默认,平衡速度和质量);
    • cv2.INTER_CUBIC:双三次插值(质量更高,速度较慢);
    • cv2.INTER_NEAREST:最近邻插值(速度快,可能产生锯齿)。
  • borderMode:边缘填充模式(旋转后边缘的空白区域处理):
    • cv2.BORDER_CONSTANT:固定颜色填充(需配合 borderValue);
    • cv2.BORDER_REPLICATE:复制边缘像素填充;
    • cv2.BORDER_REFLECT:镜像填充(如 abc → cba bc)。
  • borderValue:填充颜色(仅 borderMode=cv2.BORDER_CONSTANT 时生效):
    • 灰度图:单值(如 255 表示白色);
    • 彩色图:BGR 三通道值(如 (0, 255, 0) 表示绿色)。

例子:

import cv2
import numpy as np
import math# 读取图像
img = cv2.imread('image.jpg')
h, w = img.shape[:2]  # 原图高、宽# 1. 定义旋转参数
center = (w // 2, h // 2)  # 以图像中心为旋转中心
angle = 30  # 逆时针旋转30度
scale = 1.0  # 不缩放# 2. 计算旋转矩阵
M = cv2.getRotationMatrix2D(center, angle, scale)# 3. 计算旋转后的输出尺寸(避免内容截断)
theta = math.radians(angle)  # 角度转弧度
new_w = int(w * abs(math.cos(theta)) + h * abs(math.sin(theta)))
new_h = int(w * abs(math.sin(theta)) + h * abs(math.cos(theta)))# 4. 调整旋转矩阵以适应新尺寸(避免图像偏移)
M[0, 2] += (new_w / 2) - center[0]
M[1, 2] += (new_h / 2) - center[1]# 5. 执行旋转
rotated = cv2.warpAffine(src=img,M=M,dsize=(new_w, new_h),flags=cv2.INTER_CUBIC,  # 高质量插值borderMode=cv2.BORDER_CONSTANT,  # 固定颜色填充边缘borderValue=(255, 255, 255)  # 白色填充
)# 显示结果
cv2.imshow('Original', img)
cv2.imshow('Rotated', rotated)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果:这是我拍的小猫咪

http://www.dtcms.com/a/333393.html

相关文章:

  • 补充日志之-配置文件解析指南(Centos7)
  • 容器内部再运行Docker(DinD和DooD)
  • CUDA中的基本概念
  • Linux软件编程:进程线程(线程)
  • 结构体(Struct)、枚举(Enum)的使用
  • 基于SpringBoot的房产销售系统
  • 护栏卫士碰撞报警系统如何实时监测护栏的状态
  • 系统时钟配置
  • 38 C++ STL模板库7-迭代器
  • 用ICO图标拼成汉字
  • BFS和codetop复习
  • 复杂度扫尾+链表经典算法题
  • Klipper-probe模块
  • H5449G降压恒流无人机照明驱动芯片方案24V/36V/48V/72V降6V12V9V /8A替换NCL30160
  • 探索无人机图传技术:创新视野与无限可能
  • C#WPF实战出真汁06--【系统设置】--餐桌类型设置
  • Linux 系统中, LANG 和 LC_ALL变量有什么区别与联系?
  • 文档对比(java-diff-utils)
  • lidar2imu/auto_caliban以及manual_calib安装过程
  • 8.15网络编程——UDP和TCP并发服务器
  • qs是什么?
  • Python入门第3课:Python中的条件判断与循环语句
  • Ubuntu20.04下Remmina的VNC密码忘记后重置
  • 手机场景性能测试中的部分关键指标
  • Layui 语法详解与全功能示例
  • iOS 性能监控实战,多工具协作完成全方位分析
  • LCR 076. 数组中的第 K 个最大元素
  • 代码随想录刷题Day33
  • [优选算法专题二滑动窗口——长度最小的子数组]
  • 【完整源码+数据集+部署教程】电池柱状态检测系统源码和数据集:改进yolo11-TADDH