仿射变换矩阵实现图片任意角度翻转

先统一图像坐标与2x3矩阵含义

要用矩阵实现图片翻转或旋转,先要统一坐标系和画布范围。常见图像坐标以左上角为原点,x 轴向右增长,y 轴向下增长;宽度为 W、高度为 H 的图像,其有效像素坐标是 0 ≤ x < W0 ≤ y < H

二维仿射变换通常写成一个 2×3 矩阵:

x' = a x + c y + e
y' = b x + d y + f

它包含 6 个参数。a、b、c、d控制旋转、缩放、错切和翻转等线性变换,e、f控制平移。用齐次坐标表示时,点可写为 [x,y,1]ᵀ,矩阵则扩展为 3×3 形式:

[x'] [a c e] [x]
[y'] = [b d f] [y]
[1 ] [0 0 1] [1]

因此,2×3 矩阵并不只能旋转图片,它同样能表达缩放、镜像和位移。正向映射是把原图像素投到目标位置;实际重采样更常使用逆向映射,即遍历目标像素,反向计算它在原图中的坐标,再用插值取值。这样可以减少正向投影留下的空洞像素。

推导水平垂直翻转的坐标映射

水平翻转指左右镜像,x 坐标需要反向,y 坐标保持不变:

x' = W - 1 - x
y' = y

对应的 2×3 矩阵是:

[ -1 0 W-1 ]
[ 0 1 0 ]

垂直翻转指上下镜像:

x' = x
y' = H - 1 - y

对应矩阵是:

[ 1 0 0 ]
[ 0 -1 H-1 ]

这里的 W - 1H - 1 不能省略。像素索引通常从 0 开始,宽度为 4 的图像,x 坐标范围是 0、1、2、3;左端的 0 翻转后应到 3,所以公式是 4 - 1 - 0 = 3,而不是 4。

用一个宽 4、高 3 的图像验证水平翻转:

  • 左上角 (0,0)(3,0),即右上角。
  • 右上角 (3,0)(0,0)
  • 左下角 (0,2)(3,2)
  • 右下角 (3,2)(0,2)

如果只把缩放系数改成 -1,例如写成 x'=-x,结果会把 x 坐标映射到 0 或负数区域。这是绕原点翻转,不是在原图画布内翻转;必须补上 W-1H-1 的平移项。

水平翻转和垂直翻转也不是旋转 180°。旋转 180°等价于连续执行一次水平翻转和一次垂直翻转,两个坐标都会反向。

用矩阵实现任意角度旋转

绕坐标原点旋转角度 θ 的公式是:

x' = cosθ · x - sinθ · y
y' = sinθ · x + cosθ · y

对应矩阵为:

[ cosθ -sinθ 0 ]
[ sinθ cosθ 0 ]

矩阵中的角度计算使用 sinθcosθ。如果输入的是度数,必须先转换为弧度:θ × π / 180。例如 90°对应 π/2,不能直接把数值 90 传给三角函数。

图片通常应绕中心旋转,而不是绕左上角原点旋转。设中心为 (cx,cy)=((W-1)/2,(H-1)/2),处理过程是“平移到中心 → 旋转 → 平移回去”。展开后,仍可写成一个 2×3 矩阵,其线性部分为旋转矩阵,平移项由中心坐标和旋转角共同决定。

旋转后若要完整保留图像,画布也要调整。常用包围盒尺寸为:

W' = |W cosθ| + |H sinθ|
H' = |W sinθ| + |H cosθ|

这组公式给出的是连续几何意义上的尺寸,实际输出通常还会涉及取整。最近邻插值直接选取距离最近的像素,速度快且不会产生新颜色,但斜线容易出现锯齿;双线性插值根据周围 4 个像素加权,边缘更平滑,却可能使文字或细线略微变软。透明背景、裁剪方式和边界填充值取决于具体图像库及参数。

把矩阵参数落地到图片翻转工具

在图片翻转工具中,可以按下面的顺序实现:

  1. 读取图片,获得 WH 和颜色通道信息。
  2. 根据水平翻转、垂直翻转或旋转需求选择中心与 2×3 矩阵。
  3. 确定输出尺寸;旋转时决定是否扩展画布。
  4. 采用逆向采样,将目标坐标映射回原图坐标。
  5. 设置最近邻或双线性插值,并明确边界填充模式。
  6. 导出图片,检查透明通道、尺寸和方向。

常用接口的定位不同:

  • OpenCV 4.x 的 cv2.warpAffine():直接接收 2×3 矩阵和输出尺寸,适合精确控制矩阵、插值和边界模式。
  • Pillow 10.x 的 Image.transpose():适合水平翻转、垂直翻转和 90°等固定方向操作,代码更简单,但不直接让用户编辑完整矩阵。
  • Pillow 10.x 的 Image.rotate():适合按角度旋转,可设置是否扩展画布、插值和填充色。

OpenCV 4.x 与 Pillow 10.x 只是示例版本,具体行为取决于安装版本和参数设置。尤其要显式指定输出尺寸、旋转是否扩展画布、透明背景颜色及插值方式,否则同一张图片在不同工具中可能出现裁剪范围或边缘颜色差异。

无论使用自研代码还是站内的图片翻转工具,都可以用一张带方向标记的测试图验证结果:

  • 0°:尺寸和像素位置应保持不变。
  • 90°:检查宽高是否交换,以及文字方向是否符合预期。
  • 180°:四个角点应全部对调。
  • 水平翻转:左上角应移动到右上角。
  • 垂直翻转:左上角应移动到左下角。

如果角点正确但文字方向异常,通常是把水平翻转误认为旋转;如果图像出现黑边或透明空洞,则应检查逆向采样、输出画布尺寸和边界填充参数。

更多推荐

先把显著性图变成可裁切区域 智能裁切要解决的不是“从中心切一刀”,而是在目标宽高比下,尽量保留人物、商品和文字等重要区域。显著性检测提供注意力分布,人脸检测、目标检测和 OCR 提供明确的保护对象;两类信息结合,才适合用于实际裁切。 显

了解更多 >

说明主色提取要解决的实际问题 图片主色提取的目标,是从一张图的像素中找出 3~8 个代表颜色,生成可用于配色、设计参考或图片取色工具的主色板。输出不应只有几个色块,还应包含每种颜色的 HEX、RGB、像素占比,以及明确的排序依据。 直接按

了解更多 >

两种“补色”算法为何结果不同 “补色”在图像处理中可能指两套不同规则:一套是对 RGB 通道做数值反转,另一套是沿 HSL 色轮把色相移动 180°。它们对纯红等高饱和颜色可能得到相同或相近结果,但面对灰色、低饱和色和不同明度的颜色,视觉结

了解更多 >

用目标宽高比确定占位图尺寸 生成占位图时,先确定目标宽高比,再决定像素尺寸和填充方式。宽高比只描述图片的形状,文件体积还会受到像素数量、格式、透明通道和压缩参数影响,不能把两者混为一谈。 宽高比是宽度与高度的比例,用来描述图片形状。常见比例

了解更多 >

从 RGB 数值映射到灰度亮度 把彩色图片转成黑白,核心不是把红、绿、蓝三个数直接相加后平均,而是按照人眼对不同颜色的敏感程度分配权重。常用的 BT.601/Rec.601 亮度近似公式是: Y = 0.299R + 0.587G +

了解更多 >