【OpenCV】Python图像处理几何变换之翻转

图像翻转(Image Flipping)是常用的几何变换,指将图像沿水平、垂直或对角线方向镜像反转,核心是通过调整像素坐标的映射关系实现,不改变图像尺寸和像素值本身,仅重构像素排列顺序。OpenCV 提供 cv2.flip() 函数一键实现翻转,支持多种翻转方向,广泛用于图像数据增强(如深度学习样本扩充)、镜像显示、图像校正等场景。

一、核心原理

1. 翻转的本质

图像可视为像素组成的二维矩阵(坐标体系:左上角为原点 (0,0),向右为 x 轴正方向,向下为 y 轴正方向)。翻转的核心是像素坐标的对称映射

  • 水平翻转:左右对称,像素 (x,y) 映射到 (w-1-x, y)w 为图像宽度);
  • 垂直翻转:上下对称,像素 (x,y) 映射到 (x, h-1-y)h 为图像高度);
  • 水平垂直翻转(对角线翻转):先水平再垂直(或反之),像素 (x,y) 映射到 (w-1-x, h-1-y)

2. OpenCV 翻转方向参数

cv2.flip() 通过 flipCode 参数指定翻转方向,参数含义如下:

flipCode 参数 翻转方向 适用场景
1 水平翻转(左右镜像) 数据增强、镜像显示
0 垂直翻转(上下镜像) 图像校正、倒序显示
-1 水平 + 垂直翻转(对角镜像) 特殊视角调整、数据扩充

注意flipCode 仅支持上述三个值,若输入其他整数会报错。

二、cv2.flip() 函数详解

函数原型

python 复制代码
cv2.flip(src, flipCode, dst=None)

参数说明

参数 含义 注意事项
src 输入图像(单通道 / 多通道、灰度图 / 彩色图均可) 必须是 numpy.ndarray 类型(OpenCV 图像格式)
flipCode 翻转方向标识(1/0/-1) 严格对应水平 / 垂直 / 水平 + 垂直翻转
dst 输出图像(可选) 若不指定,函数会自动创建与 src 同尺寸、同类型的图像

返回值

翻转后的目标图像(numpy.ndarray 类型),与输入图像尺寸、通道数完全一致。

三、完整实现代码(多种场景)

1. 基础场景:灰度图 / 彩色图翻转

支持灰度图和彩色图直接翻转(无需额外通道处理),以下以彩色图为例(灰度图仅需修改读取方式):

python 复制代码
import cv2
import matplotlib.pyplot as plt

# 1. 读取图像(彩色图:cv2默认BGR格式;灰度图需加 cv2.IMREAD_GRAYSCALE)
img = cv2.imread("lena.jpg")
if img is None:
    print("无法读取图像,请检查路径!")
    exit()

# 转换为RGB格式(用于matplotlib显示,避免颜色错乱)
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 2. 三种方向翻转
flip_horizontal = cv2.flip(img, flipCode=1)  # 水平翻转(左右)
flip_vertical = cv2.flip(img, flipCode=0)    # 垂直翻转(上下)
flip_both = cv2.flip(img, flipCode=-1)       # 水平+垂直翻转(对角)

# 转换翻转后的图像为RGB格式
flip_horizontal_rgb = cv2.cvtColor(flip_horizontal, cv2.COLOR_BGR2RGB)
flip_vertical_rgb = cv2.cvtColor(flip_vertical, cv2.COLOR_BGR2RGB)
flip_both_rgb = cv2.cvtColor(flip_both, cv2.COLOR_BGR2RGB)

# 3. 显示结果
plt.figure(figsize=(15, 10))
# 原图
plt.subplot(2, 2, 1)
plt.imshow(img_rgb)
plt.title("Original Image")
plt.axis("off")
# 水平翻转
plt.subplot(2, 2, 2)
plt.imshow(flip_horizontal_rgb)
plt.title("Horizontal Flip (flipCode=1)")
plt.axis("off")
# 垂直翻转
plt.subplot(2, 2, 3)
plt.imshow(flip_vertical_rgb)
plt.title("Vertical Flip (flipCode=0)")
plt.axis("off")
# 水平+垂直翻转
plt.subplot(2, 2, 4)
plt.imshow(flip_both_rgb)
plt.title("Horizontal + Vertical Flip (flipCode=-1)")
plt.axis("off")

plt.tight_layout()
plt.show()

2. 进阶场景:视频帧实时翻转

图像翻转速度极快(无插值计算,仅坐标映射),适合实时视频处理(如直播镜像、监控画面翻转):

python 复制代码
import cv2

def video_real_time_flip(video_path=0):
    """
    实时翻转视频帧(支持摄像头或视频文件)
    :param video_path: 视频路径(0表示默认摄像头,也可传入视频文件路径如"test.mp4")
    """
    # 打开视频流
    cap = cv2.VideoCapture(video_path)
    if not cap.isOpened():
        print("无法打开视频流,请检查设备或文件路径!")
        return

    # 循环读取帧并翻转
    while True:
        ret, frame = cap.read()
        if not ret:  # 读取完毕(视频结束或摄像头断开)
            break

        # 三种翻转方式(可按需选择一种或多种显示)
        frame_h = cv2.flip(frame, 1)  # 水平翻转(常用镜像模式)
        frame_v = cv2.flip(frame, 0)  # 垂直翻转
        frame_b = cv2.flip(frame, -1) # 双翻转

        # 拼接显示(原图 + 水平翻转图)
        combined = cv2.hconcat([frame, frame_h])
        cv2.putText(combined, "Original", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,0), 2)
        cv2.putText(combined, "Horizontal Flip", (frame.shape[1]+10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,0), 2)

        # 显示窗口
        cv2.imshow("Real-Time Flip", combined)

        # 按下 'q' 退出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    # 释放资源
    cap.release()
    cv2.destroyAllWindows()

# 运行实时翻转(默认打开摄像头)
video_real_time_flip()

3. 实用场景:数据增强(批量翻转图像)

深度学习中,翻转图像是常用的数据增强手段(扩充样本多样性),以下实现批量读取图像并生成翻转样本:

python 复制代码
import cv2
import os
import glob

def batch_flip_images(input_dir, output_dir):
    """
    批量翻转文件夹中的图像,生成增强样本
    :param input_dir: 输入图像文件夹路径
    :param output_dir: 输出增强样本文件夹路径
    """
    # 创建输出文件夹(若不存在)
    os.makedirs(output_dir, exist_ok=True)

    # 读取文件夹中所有图像(支持jpg/png格式)
    image_paths = glob.glob(os.path.join(input_dir, "*.jpg")) + glob.glob(os.path.join(input_dir, "*.png"))
    if not image_paths:
        print("输入文件夹中未找到jpg/png图像!")
        return

    # 批量处理
    for idx, img_path in enumerate(image_paths):
        # 读取图像
        img = cv2.imread(img_path)
        if img is None:
            print(f"跳过无法读取的图像:{img_path}")
            continue

        # 三种翻转
        flip_h = cv2.flip(img, 1)
        flip_v = cv2.flip(img, 0)
        flip_b = cv2.flip(img, -1)

        # 获取图像文件名(不含路径)
        filename = os.path.basename(img_path)
        name, ext = os.path.splitext(filename)

        # 保存翻转后的图像
        cv2.imwrite(os.path.join(output_dir, f"{name}_h{ext}"), flip_h)  水平翻转
        cv2.imwrite(os.path.join(output_dir, f"{name}_v{ext}"), flip_v)  垂直翻转
        cv2.imwrite(os.path.join(output_dir, f"{name}_b{ext}"), flip_b)  双翻转

        print(f"处理完成:{filename} → 生成3个增强样本")

    print(f"\n批量处理结束!共处理 {len(image_paths)} 张图像,生成 {len(image_paths)*3} 个增强样本,保存至:{output_dir}")

# 运行批量增强(需提前准备input_dir文件夹并放入图像)
input_dir = "original_images"  # 输入图像文件夹
output_dir = "augmented_images" # 输出增强样本文件夹
batch_flip_images(input_dir, output_dir)

四、关键说明与应用场景

1. 翻转的核心特点

  • 无质量损失:仅改变像素排列,不修改像素值,翻转后图像与原图清晰度完全一致;
  • 速度极快 :无需插值计算(区别于缩放、旋转),时间复杂度为 O(h×w)(仅遍历一次像素),适合实时场景;
  • 可逆性 :对同一图像连续两次相同方向翻转,可还原原图(如 cv2.flip(cv2.flip(img,1),1) == img)。

2. 典型应用场景

  • 数据增强:深度学习中翻转图像(尤其是水平翻转),可扩充样本集,提升模型泛化能力(如人脸识别、物体检测);
  • 镜像显示:直播、视频通话时的 "镜像模式"(水平翻转),符合人眼观察习惯;
  • 图像校正:拍摄时倒置的图像(如手机竖拍后横屏显示),通过垂直翻转快速校正;
  • 特殊效果:游戏、影视中的镜像场景(如水中倒影可用垂直翻转实现)。

五、注意事项

  1. 颜色通道一致性:彩色图翻转后仍为 BGR 格式(cv2 默认),若用 matplotlib 显示,需先转换为 RGB 格式,否则颜色会错乱;
  2. 图像路径 :避免路径包含中文或空格,否则 cv2.imread 可能返回 None(可改用 os.path 处理路径或修改文件名);
  3. 视频流释放 :实时视频处理后,必须调用 cap.release()cv2.destroyAllWindows() 释放资源,否则会导致内存泄漏;
  4. 批量处理效率:即使处理万级像素图像,翻转速度仍极快,批量处理时瓶颈通常在图像读写(而非翻转本身),可通过多线程优化读写速度。

通过 cv2.flip() 函数,可轻松实现多种方向的图像翻转,结合批量处理或实时视频流,能满足数据增强、镜像显示等各类实际需求,是 OpenCV 中最易用且高效的几何变换之一。

相关推荐
无能者狂怒2 小时前
YOLO C++ Onnx Opencv项目配置指南
c++·opencv·yolo
劈星斩月2 小时前
OpenCV 学习9-灰度转黑白二值图像
opencv·转二值图像·threshold函数
CodeCraft Studio2 小时前
国产化PPT处理控件Spire.Presentation教程:使用Python将图片批量转换为PPT
python·opencv·powerpoint·ppt文档开发·ppt组件库·ppt api
五阿哥永琪3 小时前
Spring Boot 中自定义线程池的正确使用姿势:定义、注入与最佳实践
spring boot·后端·python
Data_agent3 小时前
Python编程实战:从类与对象到设计优雅
爬虫·python
Swizard3 小时前
别再迷信“准确率”了!一文读懂 AI 图像分割的黄金标尺 —— Dice 系数
python·算法·训练
超级大只老咪3 小时前
数组的正向存储VS反向存储(Java)
java·开发语言·python
长安牧笛4 小时前
心理健康情绪日记分析系统,用户输入文字日记后,AI提取情绪关键词,焦虑/愉悦等,生成周情绪波动曲线,并推荐调节建议。
python
艾上编程4 小时前
第三章——爬虫工具场景之Python爬虫实战:学术文献摘要爬取,助力科研高效进行
开发语言·爬虫·python