【OpenCV】第四章 图像几何变换

4.1 仿射变换

图像的几何变换在计算机视觉和图像处理中扮演着至关重要的角色。仿射变换(Affine Transformation)是一种线性变换,它能够保持直线和平行线的特性,但不一定保持角度和长度。仿射变换广泛应用于图像旋转、缩放、剪切、平移以及图像对齐等操作中。

仿射变换的数学基础

仿射变换可以由一个2x3的矩阵表示,形式如下:

这个矩阵可以应用于图像的每个像素点 (x, y) 来得到新的位置 (x', y'):

仿射变换包括以下几种基本操作:

  1. 平移(Translation):将图像整体向某个方向移动。
  2. 缩放(Scaling):调整图像的尺寸。
  3. 旋转(Rotation):将图像绕某个中心点旋转一定的角度。
  4. 剪切(Shearing):沿水平或垂直方向倾斜图像。
使用OpenCV进行仿射变换

OpenCV提供了cv2.getAffineTransform()cv2.warpAffine()两个主要函数来实现仿射变换。

  • cv2.getAffineTransform(src, dst):计算仿射变换矩阵。
    • src:源图像中的三个点。
    • dst:目标图像中对应的三个点。
  • cv2.warpAffine(src, M, dsize):应用仿射变换矩阵M到源图像。
    • src:源图像。
    • M:仿射变换矩阵。
    • dsize:输出图像的尺寸,格式为 (宽度, 高度)
示例一:图像的平移
import cv2
import numpy as np

# 读取图像
image = cv2.imread('test.jpg')

if image is not None:
    rows, cols = image.shape[:2]

    # 定义平移矩阵,向右移动100像素,向下移动50像素
    M = np.float32([[1, 0, 100],
                    [0, 1, 50]])

    # 应用平移变换
    translated = cv2.warpAffine(image, M, (cols, rows))

    # 显示结果
    cv2.imshow('Original Image', image)
    cv2.imshow('Translated Image', translated)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    # 保存结果
    cv2.imwrite('translated.jpg', translated)
else:
    print("Error: 无法读取图像文件。")

说明:

  • 平移矩阵中的10050分别表示图像将向右移动100像素,向下移动50像素。
  • cv2.warpAffine()函数根据平移矩阵将图像平移。
示例二:图像的缩放与旋转
import cv2
import numpy as np

# 读取图像
image = cv2.imread('test.jpg')

if image is not None:
    rows, cols = image.shape[:2]

    # 缩放因子
    scale_factor = 0.5

    # 定义缩放矩阵
    M_scale = np.float32([[scale_factor, 0, 0],
                          [0, scale_factor, 0]])

    # 应用缩放变换
    scaled = cv2.warpAffine(image, M_scale, (int(cols * scale_factor), int(rows * scale_factor)))

    # 定义旋转中心,通常为图像中心
    center = (cols / 2, rows / 2)

    # 定义旋转角度和缩放因子
    angle = 45  # 旋转45度
    scale = 1.0  # 不缩放

    # 获取旋转矩阵
    M_rotate = cv2.getRotationMatrix2D(center, angle, scale)

    # 计算旋转后图像的尺寸,以防止图像内容被裁剪
    abs_cos = abs(M_rotate[0, 0])
    abs_sin = abs(M_rotate[0, 1])
    bound_w = int(rows * abs_sin + cols * abs_cos)
    bound_h = int(rows * abs_cos + cols * abs_sin)

    # 调整旋转矩阵的平移部分
    M_rotate[0, 2] += bound_w / 2 - center[0]
    M_rotate[1, 2] += bound_h / 2 - center[1]

    # 应用旋转变换
    rotated = cv2.warpAffine(image, M_rotate, (bound_w, bound_h))

    # 显示结果
    cv2.imshow('Scaled Image', scaled)
    cv2.imshow('Rotated Image', rotated)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    # 保存结果
    cv2.imwrite('scaled.jpg', scaled)
    cv2.imwrite('rotated.jpg', rotated)
else:
    print("Error: 无法读取图像文件。")

说明:

  • 缩放:使用仿射矩阵进行图像缩放,将图像尺寸缩小至原来的50%。
  • 旋转
    • 使用cv2.getRotationMatrix2D()获取旋转矩阵,指定旋转中心、角度和缩放因子。
    • 计算旋转后图像的边界尺寸,调整旋转矩阵的平移部分,确保整个图像内容不被裁剪。
    • 应用旋转矩阵进行图像旋转。
示例三:图像的剪切(Shearing)

剪切变换通过倾斜图像来改变图像的形状。常见的剪切分为水平剪切和垂直剪切。

import cv2
import numpy as np

# 读取图像
image = cv2.imread('test.jpg')

if image is not None:
    rows, cols = image.shape[:2]

    # 定义水平剪切矩阵,shx为剪切因子
    shx = 0.3
    M_shear = np.float32([[1, shx, 0],
                          [0,    1, 0]])

    # 应用剪切变换
    sheared = cv2.warpAffine(image, M_shear, (int(cols + shx * rows), rows))

    # 显示结果
    cv2.imshow('Original Image', image)
    cv2.imshow('Sheared Image', sheared)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    # 保存结果
    cv2.imwrite('sheared.jpg', sheared)
else:
    print("Error: 无法读取图像文件。")

说明:

  • 水平剪切因子shx = 0.3表示图像将沿水平轴倾斜30%的比例。
  • 新的图像宽度通过cols + shx * rows计算,确保剪切后的图像内容完整显示。
仿射变换的应用场景
  1. 图像对齐:将多幅图像对齐到同一坐标系,常用于图像拼接、全景图生成等。
  2. 图像增强:通过缩放、旋转等操作改善图像质量,适用于图像预处理。
  3. 目标跟踪与识别:在实时视频中对目标进行位姿调整,提升识别准确性。
  4. 图像翻译:实现图像的移动和平移,用于数据增强等。
常见问题及解决方案
  1. 图像部分内容被裁剪

    • 原因:变换矩阵未考虑图像尺寸变化,导致部分内容超出边界。
    • 解决方案:计算变换后的图像尺寸,并相应调整变换矩阵的平移部分,确保整个图像内容完整显示。
  2. 变换后的图像失真

    • 原因:变换矩阵参数设置不当,或使用的插值方法不合适。
    • 解决方案:合理设置仿射变换矩阵参数,选择适当的插值方法(如cv2.INTER_LINEARcv2.INTER_CUBIC)以减少失真。
  3. 图像变换速度慢

    • 原因:处理高分辨率图像,或在循环中重复计算变换矩阵。
    • 解决方案:优化代码,预计算不变的变换矩阵,或调整图像分辨率以加快处理速度。
  4. 颜色空间问题

    • 原因:在处理过程中颜色空间发生变化,导致变换后的图像颜色异常。
    • 解决方案:确保在仿射变换前后保持一致的颜色空间,必要时进行色彩空间转换。
总结

仿射变换是图像几何变换中的基础操作,通过线性的仿射矩阵,可以实现图像的平移、缩放、旋转和剪切等多种变换。OpenCV提供了简洁高效的函数接口,使得仿射变换的应用变得简单直观。理解仿射变换的数学原理和OpenCV的实现方法,有助于开发者在计算机视觉和图像处理项目中灵活应用这些技术,解决实际问题。


4.2 透视变换

透视变换(Perspective Transformation)是一种更为复杂的几何变换,相比仿射变换,透视变换能够处理图像的非线性变形,保留投影的特性。它在图像校正、视角变换、图像拼接及增强现实等应用中具有重要作用。

使用OpenCV进行透视变换

OpenCV提供了cv2.getPerspectiveTransform()cv2.warpPerspective()函数来实现透视变换。

  • cv2.getPerspectiveTransform(s
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智算菩萨

欢迎阅读最新融合AI编程内容

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值