当前位置: 首页 > news >正文

OpenCV(二十二):图像的翻转与旋转

图像翻转(Image Flip)

1. 原理

图像翻转是指相对于某个轴对图像进行镜像反射。
常见翻转类型:

类型操作说明变换公式
水平翻转左右镜像(x’, y’) = (w − 1 − x, y)
垂直翻转上下镜像(x’, y’) = (x, h − 1 − y)
水平 + 垂直翻转180° 旋转(x’, y’) = (w − 1 − x, h − 1 − y)

解释:
假设图像宽度为 w,高度为 h,那么:

  • 水平翻转时,像素 (0,0) 会映射到 (w-1,0)
  • 垂直翻转时,像素 (0,0) 会映射到 (0,h-1)

2. 关键技术

  • 操作本质: 像素位置的重新映射 (Remapping),不会改变图像的尺寸。
  • 数学模型:
    • 设原图像像素坐标为 (x, y),宽度为 W,高度为H。
    • 水平翻转 (X轴, flipCode=1): 新坐标 (x’, y’) 为 (W - 1 - x, y)。
    • 垂直翻转 (Y轴, flipCode=0): 新坐标 (x’, y’) 为 (x, H - 1 - y)。
    • 水平+垂直翻转 (flipCode=-1): 新坐标 (x’, y’) 为 (W - 1 - x, H - 1 - y)。
  • 性能优化 (内存操作):
    • cv::flip() 的实现通常是极度高效的。对于单通道图像,它直接操作内存。
    • 对于水平翻转,它可以利用SIMD指令(如SSE/AVX)按行进行逆序拷贝,或者在内存中原地交换(In-place Swapping)像素对,从而避免额外的内存分配和复杂计算。
    • 对于垂直翻转,则可以按行进行内存块交换

3. OpenCV 实现

OpenCV 提供 cv2.flip() 函数:

flipped = cv2.flip(src, flipCode)
参数含义
flipCode = 0垂直翻转(上下)
flipCode = 1水平翻转(左右)
flipCode = -1水平 + 垂直翻转(180°)

4. Python 示例

import cv2
import matplotlib.pyplot as plt# 中文支持(避免乱码)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False# 读取图像
img = cv2.imread("example.jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 翻转操作
flip_h = cv2.flip(img, 1)    # 水平翻转
flip_v = cv2.flip(img, 0)    # 垂直翻转
flip_hv = cv2.flip(img, -1)  # 水平+垂直翻转# 显示结果
titles = ['原图', '水平翻转', '垂直翻转', '水平+垂直翻转']
images = [img, flip_h, flip_v, flip_hv]plt.figure(figsize=(10, 6))
for i in range(4):plt.subplot(1, 4, i+1)plt.imshow(images[i])plt.title(titles[i])plt.axis('off')
plt.tight_layout()
plt.show()

执行效果:

在这里插入图片描述

图像旋转(Image Rotation)

1. 原理

图像旋转是绕某个点(通常是图像中心)按一定角度旋转。
每个像素的新坐标通过旋转矩阵计算得到:

在这里插入图片描述

其中:

  • θ 是旋转角度;
  • (tx, ty) 是平移量,用于保证图像旋转后仍在画布内。

2. 关键技术

任意角度旋转 (通过仿射变换)

OpenCV中通过 cv::getRotationMatrix2D() 生成旋转矩阵,再通过 cv::warpAffine() 应用变换。

关键原理与底层技术:

  1. 确定旋转中心与缩放 (Scaling):

    • 通常以图像中心作为旋转中心 (Cx, Cy)。
    • cv::getRotationMatrix2D() 允许定义旋转中心、角度和可选的缩放因子。
  2. 生成 2x3 仿射变换矩阵 (Affine Matrix):

    • 旋转操作包括三个步骤的矩阵组合:

      1. 平移 (Translation):将旋转中心移到原点。
      2. 旋转 (Rotation):绕原点旋转 θ\thetaθ 角度。
      3. 平移 (Translation):将原点移回旋转中心。
    • 最终的仿射矩阵 M 为:

      在这里插入图片描述

      其中

      在这里插入图片描述

  3. 应用变换与插值 (Warping and Interpolation):

    • cv::warpAffine() 使用逆向映射 (Inverse Mapping) 来填充目标图像的每个像素。
    • 对于目标图像中的每个像素 (x’, y’),通过 M-1 计算其在原图中的浮点坐标 (x, y)。
    • 由于 (x, y) 通常不是整数,需要通过插值(如双线性插值 INTER_LINEAR 或三次样条插值 INTER_CUBIC)来计算其像素值。
    • 关键技术: 插值是决定旋转后图像质量(平滑度、锐度)和计算耗时的核心。
  4. 计算新尺寸:

    • 旋转后图像的尺寸通常会增大,以容纳所有原图像的像素,避免裁剪。新尺寸由原图像的四个角点经过仿射变换后所形成的新边界框决定。

特殊角度旋转 (90°/180°/270°/整倍数)

OpenCV中通过 cv::rotate() 函数实现,速度比仿射变换快得多。

关键原理与底层技术:

  • 操作本质: 简单的坐标置换和翻转,不需要复杂的矩阵乘法和插值。
  • 数学模型 (以 90° 顺时针旋转为例):
    • 原坐标 (x, y),尺寸 (W, H)。
    • 新坐标 (x’, y’) 为 (H - 1 - y, x)。
    • 新尺寸变为 (H, W) (宽变高,高变宽)。
  • 性能优化 (内存操作):
    • 无插值: 这是其速度快的核心原因。cv::rotate() 是一个直接映射操作,不涉及浮点运算和插值。
    • 内存块操作: 它的实现通常优化为对内存块进行高效的读写和重排。对于 180° 旋转,其性能可以接近于简单的翻转操作。

3. OpenCV 实现方式

(1)90/180/270° 整角旋转

使用内置函数 cv2.rotate()

rot90 = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
rot180 = cv2.rotate(img, cv2.ROTATE_180)
rot270 = cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE)

⚡ 这种方式速度最快,因为只是像素索引重新排列。

(2)任意角度旋转

使用 cv2.getRotationMatrix2D() + cv2.warpAffine()

import numpy as np(h, w) = img.shape[:2]
center = (w // 2, h // 2)# 旋转 45°
angle = 45
scale = 1.0# 1. 获取旋转矩阵
M = cv2.getRotationMatrix2D(center, angle, scale)
# 2. 仿射变换
rotated = cv2.warpAffine(img, M, (w, h))

说明:

  • getRotationMatrix2D(center, angle, scale) 返回一个 2×3 仿射矩阵;
  • warpAffine() 根据该矩阵完成像素映射;
  • 默认旋转方向:逆时针

4. 完整 Python 示例(翻转 + 旋转)

import cv2
import numpy as np
import matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False# 读取图像
img = cv2.imread("example.jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 翻转
flip_h = cv2.flip(img, 1)
flip_v = cv2.flip(img, 0)# 旋转 45°、90°、180°
h, w = img.shape[:2]
center = (w // 2, h // 2)
M45 = cv2.getRotationMatrix2D(center, 45, 1.0)
M90 = cv2.getRotationMatrix2D(center, 90, 1.0)
M180 = cv2.getRotationMatrix2D(center, 180, 1.0)rot45 = cv2.warpAffine(img, M45, (w, h))
rot90 = cv2.warpAffine(img, M90, (w, h))
rot180 = cv2.warpAffine(img, M180, (w, h))# 显示结果
titles = ['原图', '水平翻转', '垂直翻转', '旋转45°', '旋转90°', '旋转180°']
images = [img, flip_h, flip_v, rot45, rot90, rot180]plt.figure(figsize=(12, 8))
for i in range(6):plt.subplot(2, 3, i+1)plt.imshow(images[i])plt.title(titles[i])plt.axis('off')
plt.tight_layout()
plt.show()

执行效果:

在这里插入图片描述

关键技术对比总结

特性图像翻转 (cv::flip)任意角度旋转 (cv::warpAffine)特殊角度旋转 (cv::rotate)
数学基础简单坐标映射仿射变换矩阵简单坐标置换
尺寸变化不变通常增大90°/270°时:宽高互换
核心挑战内存高效存取/交换插值运算(决定质量)内存块重排
性能极快 (通常利用SIMD/原地操作)慢 (涉及浮点/插值) (直接映射,无插值)
适用场景镜像、180°旋转任意角度、缩放、斜切等严格的 90°/180°/270° 旋转
http://www.dtcms.com/a/589086.html

相关文章:

  • 权限维持:操作系统后门技术分析与防护
  • 网闸与防火墙:构建纵深防御的“门卫”与“断桥”
  • 室内设计找工作网站wordpress app源码
  • 河北seo网站优化公司光辉网站建设
  • android 网络访问拦截器使用后的bug处理
  • mysql视图和存储过程
  • VRRP的补充
  • 天津 交友 网站建设自建网站做外贸谷歌推广
  • Young GC 的触发时机
  • 专业做网站照片免费咨询法律律师电话号码
  • GAN vs. VAE:生成对抗网络 vs. 变分自编码机
  • Docker打包步骤
  • 【数据集+源码】基于yolov11+streamlit的玉米叶片病虫害检测系统
  • VP8 是什么?
  • Rust底层编程:安全与性能的完美平衡
  • 如何删除自己建的网站无忧网站建设公司
  • HTTP-大文件传输处理
  • [linux仓库]线程同步与生产者消费者模型[线程·陆]
  • 【算法】day17 多维动态规划
  • 网站建设费算什么费用山东青岛网站建设seo优化
  • 【复习】计网每日一题1109---iBGP、AS
  • 30.注意力汇聚:Nadaraya-Watson 核回归
  • 广州营销型网站建设培训班网站设计制作太原
  • RV1126 NO.46:RV1126+OPENCV对视频流进行视频膨胀操作
  • 分布式的cap,base,raft
  • 2025年11月份下半年系统架构师真题(回忆版)
  • C语言刷题-编程(一)(基础)
  • 日常踩用的坑笔记
  • dede制作的网站挂马中国深圳航空公司官网
  • 网站开发工作需要什么专业织梦如何做网站