问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

用矩阵实现镜像变换

创作时间:
作者:
@小白创作中心

用矩阵实现镜像变换

引用
1
来源
1.
http://www.math345.com/blog/article/39

镜像变换是图像处理中的基本操作之一,广泛应用于图形学、计算机视觉等领域。本文将从数学的角度深入探讨如何使用矩阵实现镜像变换,并通过Python代码演示具体实现方法。

在数学345视频号第14期《对称》中我们讲到了镜像对称。镜像对称可以通过镜像变换实现。镜像变换通常是关于某个轴或直线做翻转操作操作。 在图像处理中,常见的是水平镜像和垂直镜像。

水平镜像是关于垂直中轴线的镜像,即图像沿着垂直中轴线左右翻转。如下图:

垂直镜像是关于水平中轴线的镜像,即图像沿着水平中轴线上下翻转。如下图:

理解了镜像变换,并且你熟悉矩阵乘法运算的话,不难想出,镜像变换矩阵,其实就是单位矩阵的"镜像矩阵",假设镜像矩阵为M,则
\begin{align*} M = \left(\begin{array}{cccc} 0 & \cdots & 0 & 1 \ 0 & \cdots & 1 & 0 \ \vdots & & \vdots & \vdots \ 1 & \cdots & 0 & 0 \end{array}\right) \end{align*}

和单位矩阵I放在一起,你可以看到对称之美!数学之美!
\begin{align*} I=\left(\begin{array}{cccc} 1 & 0 & \cdots & 0 \ 0 & 1 & \cdots & 0 \ \vdots & \vdots & & \vdots \ 0 & 0 & \cdots & 1 \end{array}\right) \end{align*}

假设图像为$A_{m,n}$为mn矩阵,即高为m,宽为n,则
[ A_{m,n} \times M_{n,n} ]
表示对图像A做水平镜像变换,其中M为 n
n 镜像矩阵。

同样的道理,
[M_{m, m} \times A_{m, n}]
则表示对图像A做垂直镜像变换。

在仿射变换中的旋转缩放变换矩阵推导的文章中,我们介绍过“仿射变换可以将矩形转换为平行四边形,可以挤压形状,但是必须保持两边平行。常见的是旋转、缩放、平移变换。” 。现在思考下,镜像变换是仿射变换吗?

实际上,镜像变换也可以用仿射变换矩阵来实现。因为对于二维空间中的点 (x,y),执行水平镜像变换可以表示为:
\begin{align*} \left[\begin{array}{ccc} -1 & 0 & \text { width } \ 0 & 1 & 0 \end{array}\right]\left[\begin{array}{l} x \ y \ 1 \end{array}\right] \end{align*}
其中 width 是图像的宽度。这个矩阵乘以点 (x,y) 会产生镜像后的点 $(x', y')$。这个矩阵乘以二维坐标点时,第一行的 x 系数为 -1,表示将点绕着 y 轴进行了翻转,即进行了水平镜像变换。第二行的 y 系数为 1,表示不对点进行垂直方向上的变换,保持原样。第一行的 width 项则是表示进行 width 平移,目的是为了保持变换后图像的位置不变,保证图像显示在原来的位置上。

垂直镜像变换与此类似,可以表示为:
\begin{align*} \left[\begin{array}{ccc} 1 & 0 & 0 \ 0 & -1 & \text{height} \end{array}\right]\left[\begin{array}{l} x \ y \ 1 \end{array}\right] \end{align*}
其中 height 是图像的高度。

上面两个矩阵都是仿射变换矩阵,因此镜像变换也属于仿射变换。

用 python 代码非常容易实现镜像变换

import cv2
import numpy as np

def mirror_transform(image_path, horizontal=True):
    # 加载图片
    original_image = cv2.imread(image_path)
    # 检查是否成功加载图片
    if original_image is None:
        print("Error: 无法加载图片!")
        return
    # 获取图片尺寸
    height, width = original_image.shape[:2]
    # 创建镜像变换矩阵
    if horizontal:
        mirror_matrix = np.float32([[-1, 0, width],
                                    [0, 1, 0]])
    else:
        mirror_matrix = np.float32([[1, 0, 0],
                                    [0, -1, height]])
    # 进行镜像变换
    mirrored_image = cv2.warpAffine(original_image, mirror_matrix, (width, height))
    # 显示变换后的图片
    cv2.imshow("Mirrored Image", mirrored_image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

image_path = "example.jpg"
mirror_transform(image_path, True)
mirror_transform(image_path, False)
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号