图像翻转(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. 典型应用场景
- 数据增强:深度学习中翻转图像(尤其是水平翻转),可扩充样本集,提升模型泛化能力(如人脸识别、物体检测);
- 镜像显示:直播、视频通话时的 "镜像模式"(水平翻转),符合人眼观察习惯;
- 图像校正:拍摄时倒置的图像(如手机竖拍后横屏显示),通过垂直翻转快速校正;
- 特殊效果:游戏、影视中的镜像场景(如水中倒影可用垂直翻转实现)。
五、注意事项
- 颜色通道一致性:彩色图翻转后仍为 BGR 格式(cv2 默认),若用 matplotlib 显示,需先转换为 RGB 格式,否则颜色会错乱;
- 图像路径 :避免路径包含中文或空格,否则
cv2.imread可能返回None(可改用os.path处理路径或修改文件名); - 视频流释放 :实时视频处理后,必须调用
cap.release()和cv2.destroyAllWindows()释放资源,否则会导致内存泄漏; - 批量处理效率:即使处理万级像素图像,翻转速度仍极快,批量处理时瓶颈通常在图像读写(而非翻转本身),可通过多线程优化读写速度。
通过 cv2.flip() 函数,可轻松实现多种方向的图像翻转,结合批量处理或实时视频流,能满足数据增强、镜像显示等各类实际需求,是 OpenCV 中最易用且高效的几何变换之一。