目录
背景
仿射变换(Affine Transformation)是几何学中一种重要的线性变换,广泛应用于图像处理、计算机视觉和图形学等领域。它包括平移、旋转、缩放、剪切等操作,能够保持图像的"仿射性",即保持点的共线性和平行线不变。仿射变换可以通过矩阵运算来表示,通常使用一个 2×3 的变换矩阵来实现对二维图像的处理。与线性变换不同的是,仿射变换允许在变换过程中加入平移操作,使其更具灵活性和实用性。在实际应用中,仿射变换常用于图像的几何校正、目标对齐、图像配准等任务,是图像处理中不可或缺的基础工具之一。
普通坐标表示法
使用 n 维坐标来表示 n维图形,对于2 维图像,用 **[ x , y ]**行向量或列向量表示
基本的变换包括 3类:平移变换、比例变换、旋转变换
平移变换
即图像的平移,只需在向量上加上一个增量向量即可:
比例变换
即图像的拉伸、收缩,比例变换是让 x、y坐标乘一个数,进行缩放,需乘一个二维矩阵:
旋转变换
即图像的旋转,其中,****是图形以坐标为旋转中心旋转的角度:
上面的变换矩阵都是基于列向量的,要是想基于行向量,仅需将变换矩阵转置一下即可
除了上面的一些基本变换,还可以将这三个基本变换进行组合,形成对称、错切等变换。
齐次坐标表示法
普通坐标表示法有一个很大的问题,进行多个基本变换的混合时,平移变换是加一个向量、旋转和比例变换是乘一个矩阵,无法统一表示,这时就需要用齐次坐标表示法:
齐次坐标表示法是一种数学工具,用于在 n 维空间中描述点和向量,通过增加一个额外的维度来简化几何变换的计算。对于二维空间中的点 (x, y) ,其齐次坐标形式为 (xh, yh, h) ,其中 h 是非零的比例因子,通常取为 1 ,以便于计算。这种表示法允许所有仿射变换(包括平移、旋转、缩放)以矩阵乘法的形式统一表达,极大地方便了计算机图形学和图像处理中的应用。例如,在二维空间中使用 3×3 矩阵可以简洁地实现这些变换,而在三维空间中则使用4×4 矩阵。这种方法不仅简化了变换过程,也便于进行透视变换等复杂操作。
基于齐次坐标的三个基本变换公式为:
平移变换
比例变换
旋转变换
有了齐次坐标,对于一些混合变换,变换矩阵的维数是一样的,仅需要对各个变换矩阵相乘即可得到最终变换矩阵。
例如对任意一点(非原点)做比例变换,则需将该点先平移到原点,相对原地做比例变换后,再平移回去。
变换矩阵:
仅需将最后的变换矩阵带入即可:
上面的变换矩阵都是基于列向量的,要是想基于行向量,仅需将变换矩阵转置一下即可
代码
这些运算设计矩阵运算,虽然直接编写代码会比较复杂,但 opencv库已经为我们封装好了相关函数,直接调用就好。
也希望大家在编程过程中使用相关库时,最好理解其意,而不是直接 AI ,当 CV 工程师(Ctrl+C、Ctrl+V),就算 AI 的代码,也得理解其意,应当把 AI 当作学习的工具,而不是纯......,不然已经企业招人直接招 AI 了,还要你干嘛,而且学习原理过程中也能添加成就感、为代码生活增添一番风趣。
opencv 库下载:
python
pip install opencv-python
引入:
python
import cv2
应用:
python
import cv2
import numpy as np
# 读取图像
image = cv2.imread(r"D:\tcy_works\data\DJI\org_8b46fca2adb21a34_1751624788000.jpg")
# 获取图像尺寸
rows, cols, _ = image.shape
# 平移变换
def translate(image, tx, ty):
# 定义平移矩阵
matrix = np.float32([[1, 0, tx], [0, 1, ty]])
translated = cv2.warpAffine(image, matrix, (cols, rows))
return translated
# 旋转变换
def rotate(image, angle, center=None, scale=1.0):
# angle 正逆负顺
# scale 缩放因子,不进行缩放设置为1
if center is None:
center = (cols // 2, rows // 2)
# 计算旋转矩阵
matrix = cv2.getRotationMatrix2D(center, angle, scale)
# 应用旋转矩阵
rotated = cv2.warpAffine(image, matrix, (cols, rows))
return rotated
# 拉伸变换(缩放变换)
def stretch(image, fx, fy):
stretched = cv2.resize(image, None, fx=fx, fy=fy, interpolation=cv2.INTER_LINEAR)
# INTER_LINEAR 双线性插值
return stretched
# 应用变换
translated_image = translate(image, 50, 30) # 向右平移50像素,向下平移30像素
rotated_image = rotate(image, 45) # 绕中心点逆时针旋转45度
stretched_image = stretch(image, 1.5, 1.5) # 在x轴和y轴方向上都放大1.5倍
# 显示结果
cv2.imshow('Translated Image', translated_image)
cv2.imshow('Rotated Image', rotated_image)
cv2.imshow('Stretched Image', stretched_image)
cv2.imwrite("Translated_Image.jpg", translated_image)
cv2.imwrite('Rotated_Image.jpg', rotated_image)
cv2.imwrite('Stretched_Image.jpg', stretched_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
感谢您的观看!!!