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

计算机视觉(opencv)——仿射变换(Affine Transformation)

仿射变换(Affine Transformation)详解与OpenCV实现

一、前言

在计算机视觉与图像处理领域,图像的几何变换是非常基础而重要的内容。其中,仿射变换(Affine Transformation) 是一种保持“直线性和平行性”的线性几何变换方法。它能实现图像的旋转、平移、缩放、剪切和翻转等多种变换形式,同时仍然保持物体形状的整体结构不变。

本文将从仿射变换的数学原理变换矩阵构建OpenCV实现方式等角度进行全面讲解,并通过完整的 Python + OpenCV 实例演示整个过程。


二、仿射变换的数学原理

1. 基本概念

仿射变换是一种线性变换与平移的组合。对于任意二维空间点 ((x, y)),经过仿射变换后得到的新坐标 ((x', y')) 可表示为:

其中:

  • 线性变换矩阵,控制旋转、缩放、剪切等;

  • 平移向量

  • 整个式子称为 二维仿射变换矩阵

在 OpenCV 中,仿射矩阵通常写成如下形式(2×3矩阵):


2. 仿射变换的几何特性

仿射变换具有以下特性:

特性含义
保持直线性直线仍为直线,不会弯曲。
保持平行性平行线仍保持平行。
不保持长度变换后长度可能变化。
不保持角度变换后角度可能改变。
保持比例性同一直线上的比例关系保持不变。

正因为这些性质,仿射变换常用于:

  • 图像校正与矫正(例如将倾斜的图片恢复正位)

  • 图像增强与配准

  • 摄像头视角变换

  • 人脸对齐、姿态变换等任务


三、OpenCV中的仿射变换函数

在 OpenCV 中,主要涉及两个核心函数:

  1. cv2.getAffineTransform()

  2. cv2.warpAffine()

下面分别讲解其作用与使用方法。


1. cv2.getAffineTransform(src, dst)

该函数根据原始图像与目标图像上对应的三个点坐标,计算出一个 2×3 的仿射变换矩阵

函数原型:

cv2.getAffineTransform(src, dst)

参数说明:

  • src:原图上的三个点坐标(类型为 np.float32)。

  • dst:目标图上的对应三个点坐标。

  • 返回:2×3 的仿射变换矩阵 M。

注意:需要提供 恰好三个非共线点 才能唯一确定仿射变换。


2. cv2.warpAffine(src, M, dsize, flags=None, borderMode=None, borderValue=None)

该函数根据计算好的仿射矩阵 M 对图像进行几何变换。

函数原型:

cv2.warpAffine(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)

参数说明:

参数含义
src输入图像
M2×3 仿射变换矩阵
dsize输出图像的尺寸 (width, height)
flags插值方式(如 cv2.INTER_LINEAR, cv2.INTER_CUBIC 等)
borderMode边界像素的处理方式(如 cv2.BORDER_CONSTANT, cv2.BORDER_REFLECT
borderValue当 borderMode 为恒定边框时使用的填充值

四、仿射变换实例讲解

下面我们通过一段完整的 Python 代码演示仿射变换的全过程。

import cv2
import numpy as np"""---------------------仿射变换---------------------"""
img = cv2.imread('face1.jpg')
height, width = img.shape[:2]# 在原图像和目标图像上各选择三个点
mat_src = np.float32([[0, 0], [0, height - 1], [width - 1, 0]])
mat_dst = np.float32([[0, 0], [100, height - 100], [width - 100, 100]])M = cv2.getAffineTransform(mat_src, mat_dst)  # 得到变换矩阵# warpAffine(src, M, dsize, ...)
dst = cv2.warpAffine(img, M, dsize=(width, height))# 拼接显示
imgs = np.hstack([img, dst])
cv2.namedWindow('imgs', cv2.WINDOW_NORMAL)
cv2.imshow("imgs", imgs)
cv2.waitKey(0)

1. 代码解读

(1)读取图像与尺寸信息
img = cv2.imread('face1.jpg')
height, width = img.shape[:2]

shape[:2] 返回图像的高和宽,后续用于设定目标变换范围。


(2)定义对应点
mat_src = np.float32([[0, 0], [0, height - 1], [width - 1, 0]])
mat_dst = np.float32([[0, 0], [100, height - 100], [width - 100, 100]])

这里定义了两组三点:

  • mat_src:原始图像中的三个参考点;

  • mat_dst:目标图像中这三个点的新位置。

仿射矩阵由这三组对应关系自动计算。


(3)计算仿射矩阵
M = cv2.getAffineTransform(mat_src, mat_dst)

假设我们输出的矩阵为:

这表明图像被同时进行了平移、旋转与剪切


(4)执行仿射变换
dst = cv2.warpAffine(img, M, dsize=(width, height))

此时,OpenCV 对每个像素执行坐标映射与插值计算,生成新的变换图像。


(5)可视化对比
imgs = np.hstack([img, dst])
cv2.namedWindow('imgs', cv2.WINDOW_NORMAL)
cv2.imshow("imgs", imgs)
cv2.waitKey(0)

np.hstack() 将两张图像横向拼接展示,方便观察效果差异。
结果中左边是原图,右边是经过仿射变换后的图像。


五、仿射矩阵的物理意义

仿射矩阵中的参数可以分解为若干几何操作的组合。
若将矩阵写作:

则其几何意义如下:

参数作用数学意义
a, d控制缩放大于1放大,小于1缩小
b, c控制旋转与剪切产生倾斜效果
t_x, t_y控制平移水平或垂直移动图像

例如:

因此,仿射变换实际上是旋转、缩放、平移、剪切的复合操作。


六、仿射变换的常见应用

  1. 人脸对齐(Face Alignment)
    通过仿射变换将两眼与嘴的位置对齐,便于后续特征提取。

  2. 图像几何校正
    修正倾斜的文档或场景图像。

  3. 摄像头角度变换(视角矫正)
    将摄像机不同角度拍摄的图像对齐到统一视角。

  4. 数据增强(Data Augmentation)
    在深度学习中,通过随机仿射变换生成更多训练样本。

  5. 仿射配准(Affine Registration)
    在医学影像、卫星遥感中,用于对齐不同时间的图像。


七、与透视变换的区别

特征仿射变换透视变换
输入点数3 对点4 对点
矩阵维度2×33×3
是否保持平行性
是否支持透视深度
常见用途平移、旋转、缩放、剪切投影校正、角度变化、场景变换

简言之,仿射变换不能产生“透视效果”,而透视变换(cv2.warpPerspective)可以让平面产生三维投影的视觉变化。


八、插值与边界处理

1. 插值方式(flags)

  • cv2.INTER_NEAREST:最近邻插值,速度快但锯齿多;

  • cv2.INTER_LINEAR:双线性插值,常用;

  • cv2.INTER_CUBIC:三次插值,质量更高但计算量大。

2. 边界模式(borderMode)

  • cv2.BORDER_CONSTANT:填充常数(默认0);

  • cv2.BORDER_REFLECT:镜像填充;

  • cv2.BORDER_REPLICATE:复制边缘像素。

例如:

dst = cv2.warpAffine(img, M, (width, height), borderMode=cv2.BORDER_REFLECT)

可以避免边缘出现黑色区域。


九、实验拓展:随机仿射数据增强

我们还可以用仿射矩阵实现随机旋转和平移,增强数据集:

rows, cols = img.shape[:2]
angle = np.random.uniform(-15, 15)
scale = np.random.uniform(0.9, 1.1)
M = cv2.getRotationMatrix2D((cols/2, rows/2), angle, scale)
dst = cv2.warpAffine(img, M, (cols, rows))

这段代码让图片在 ±15° 范围内随机旋转并随机缩放,有助于提高模型泛化能力。


十、总结

仿射变换是图像几何变换中最常用的技术之一,兼具数学的优雅与工程实用性。它通过三点对应法求出变换矩阵,实现平移、旋转、缩放、剪切等多种操作,同时保持图像的几何直线关系。

在 OpenCV 中:

  • cv2.getAffineTransform() 用于计算仿射矩阵;

  • cv2.warpAffine() 用于执行变换。

通过理解其数学原理与参数意义,我们可以更灵活地控制图像几何结构,实现从视觉校正到数据增强的各种应用。


总结要点回顾:

  1. 仿射变换矩阵是 2×3;

  2. 需提供 3 对非共线点;

  3. warpAffine 实现平移、旋转、缩放、剪切;

  4. 可搭配不同插值与边界模式;

  5. 广泛应用于人脸对齐、文档矫正、数据增强等领域。

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

相关文章:

  • Hadess入门到实战(11) - 如何导入Nexus制品,实现平滑迁移
  • Spring内置功能
  • Windows离线安装OpenSSH.Server
  • 【SELinux】解决 systemd 服务因权限问题无法启动(203/EXEC)的完整方案
  • maven下载与安装及在IDEA中配置maven
  • 云南省建设工程标准定额网站挣钱最快的游戏
  • git执行git remote关联了仓库后的.git文件夹目录下到底是些什么东西?优雅草卓伊凡
  • SpringBoot+Hutool+Vue实现导出
  • 中山建设厅网站首页山东济南网站推广
  • ⸢ 柒-Ⅲ⸥⤳ 可信纵深防御建设方案:数据使用可信端安全可信
  • PHP多维数组按指定字段排序usort自定义排序方法(或使用太空船操作符 <=> 进行比较,默认按升序排序)
  • Ubuntu 20.04 安装 Redis
  • etcd节点噶了导致的k8s集群瘫痪处理参考——筑梦之路
  • stm32底层项目20251011
  • http://localhost:7474/browser/ 登陆之后账号密码neo4j / neo4j 不对 页面出现以下:
  • 网站后台添加不了图片2008r2做网站
  • 学工网站建设博物馆网站建设说明
  • RabbitMQ概述,Rabbitmq是什么
  • C 语言12:字符串函数全解析
  • 国家城乡建设规划部网站邢台专业网站建设价格
  • 三层架构:解耦 JavaWeb 开发的核心范式
  • MySQL————表的约束
  • 速度达24.3MB/s,最新精简可用版!
  • 分业务采用差异化模式:全面提升 SQL Server 系统的并发性能、可靠性与数据准确性
  • 【Linux】应用层自定义协议与序列化
  • 文件上传漏洞: .htaccess文件
  • 【GD32】软件I2C
  • 温州产品推广网站服务网站建设方案
  • 08-docker综合应用
  • 电商网站建设与运营哦在线图片编辑助手