当前位置: 首页 > 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.lryc.cn/news/621552.html

相关文章:

  • 《Effective Java》第1条:用静态工厂方法代替构造器
  • 【R语言】R 语言中 gsub 与正则表达式详解(含 POSIX 与 Perl 风格实例)
  • 【R语言】更换电脑后,如何在新设备上快速下载原来设备的 R 包?
  • 智能体开发实战:用Deepseek做一个生成思维导图的智能体
  • 2025高防IP vs 普通IP:本质差异与选型指南
  • 移动板房的网络化建设
  • StarRocks集群部署
  • 39 C++ STL模板库8-容器1-array
  • 常见IP模块的仲裁策略和实现
  • YOLO11分割模型使用rknn2量化部署
  • 网络安全蓝队常用工具全景与实战指南
  • 【DDIA】第二部分:分布式数据
  • 从零到一:发布你的第一个 npm 开源库(2025 终极指南)
  • Elasticsearch赋能规章制度智能检索:从海量文档到秒级响应
  • app-5 控制卡升级
  • 【CV 目标检测】②R-CNN模型
  • 「iOS」————UITableView性能优化
  • GCC深度剖析:从编译原理到嵌入式底层实战
  • 阿里云出里两款新的云服务器
  • 基于单片机的超市储物柜设计
  • 打破传统局限,人工智能+虚拟仿真赋能日化品设计实验教学
  • 异步并发×编译性能:Dart爬虫的实战突围
  • 笔试——Day39
  • Python洛谷做题39:P5729 【深基5.例7】工艺品制作
  • 【题解|两种做法】[ZJOI2008] 洛谷 P2600 瞭望塔[半平面交]
  • 第十章 项目进度管理-10.3 规划进度管理
  • Mini MAX AI应用矩阵测评报告——基于旗下多款产品的综合体验与行业价值分析
  • 【大模型微调系列-02】 深度学习与大模型初识
  • 《WINDOWS 环境下32位汇编语言程序设计》第1章 背景知识
  • uniapp纯前端绘制商品分享图