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

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

1. 缩放

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

1.1 插值方法

最近邻插值

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

python 复制代码
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 提供的一个图像翻转函数,用于按照指定的轴对图像进行镜像翻转操作。通过这个函数,可以实现水平翻转、垂直翻转或同时进行水平和垂直翻转。

python 复制代码
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 中用于对图像进行仿射变换的函数,可以实现平移、旋转、缩放等操作。以下是函数的详解。

python 复制代码
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 代码示例。我们将通过设置不同的仿射变换矩阵实现这些操作。

完整代码示例
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)等场景。它可以通过一组点对应关系计算出两幅图像之间的几何变换。

python 复制代码
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:计算单应性矩阵
python 复制代码
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:图像透视变换
python 复制代码
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()
相关推荐
鹏码纵横13 分钟前
已解决:java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 异常的正确解决方法,亲测有效!!!
java·python·mysql
仙人掌_lz15 分钟前
Qwen-3 微调实战:用 Python 和 Unsloth 打造专属 AI 模型
人工智能·python·ai·lora·llm·微调·qwen3
猎人everest42 分钟前
快速搭建运行Django第一个应用—投票
后端·python·django
猎人everest1 小时前
Django的HelloWorld程序
开发语言·python·django
chusheng18401 小时前
2025最新版!Windows Python3 超详细安装图文教程(支持 Python3 全版本)
windows·python·python3下载·python 安装教程·python3 安装教程
别勉.2 小时前
Python Day50
开发语言·python
美林数据Tempodata2 小时前
大模型驱动数据分析革新:美林数据智能问数解决方案破局传统 BI 痛点
数据库·人工智能·数据分析·大模型·智能问数
硅谷秋水2 小时前
NORA:一个用于具身任务的小型开源通才视觉-语言-动作模型
人工智能·深度学习·机器学习·计算机视觉·语言模型·机器人
whoarethenext2 小时前
使用 C/C++的OpenCV 裁剪 MP4 视频
c语言·c++·opencv
正儿八经的数字经2 小时前
人工智能100问☞第46问:AI是如何“学习”的?
人工智能·学习