2、OpenCV基础回顾:图像读取、显示、保存,色彩空间转换(BGR、RGB、GRAY)
好,咱们正式开始动手。这一章我带你快速过一遍 OpenCV 最核心的基础操作。别小看这些,我见过不少项目后期出 bug,追根溯源都是最开始的读写和颜色空间搞错了。
2.1 图像读取:imread 的隐藏细节
OpenCV 读取图像用 cv2.imread()。语法很简单,但有几个参数你得上心。
import cv2
# 默认以彩色模式读取 (BGR)
img = cv2.imread('cat.jpg')
# 以灰度模式读取
img_gray = cv2.imread('cat.jpg', cv2.IMREAD_GRAYSCALE)
# 读取包含透明通道的图像
img_unchanged = cv2.imread('cat.png', cv2.IMREAD_UNCHANGED)
我曾经踩过的坑:路径别带中文!OpenCV 的 imread 对中文路径支持很差,返回 None 还不报错。你排查半天,结果只是文件夹名字有个“测试”。我现在的习惯是:所有图像路径统一用英文,或者用
os.path.join() 拼接。
另外,imread 返回 None 时不会抛异常。所以读取后一定要加个判断:
if img is None:
print("图像加载失败,检查路径")
exit()
| 标志 | 值 | 说明 |
|---|---|---|
cv2.IMREAD_COLOR |
1 | 默认,加载为 BGR 三通道,忽略透明通道 |
cv2.IMREAD_GRAYSCALE |
0 | 加载为单通道灰度图 |
cv2.IMREAD_UNCHANGED |
-1 | 保留所有通道,包括 alpha |
2.2 图像显示与保存
显示图像用 cv2.imshow(),配合 cv2.waitKey() 和 cv2.destroyAllWindows() 才能正常关闭窗口。
cv2.imshow('My Image', img)
cv2.waitKey(0) # 等待任意按键
cv2.destroyAllWindows()
我个人的习惯:调试时我会把
waitKey(0) 改成 waitKey(1) 配合循环,这样能实时看到处理效果。但正式演示时还是用 0,免得画面一闪而过。
保存图像用 cv2.imwrite()。注意,保存的质量和格式有关:
# 保存为 PNG(无损)
cv2.imwrite('output.png', img)
# 保存为 JPEG,指定质量 95(0-100)
cv2.imwrite('output.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, 95])
注意:imwrite 保存的是 BGR 顺序。如果你用 matplotlib 的
plt.imshow() 显示,颜色会偏蓝偏黄。为什么?因为 matplotlib 默认用 RGB。这个问题我当年调了半小时才反应过来。
2.3 色彩空间转换:BGR、RGB、GRAY
这是本章的重头戏。OpenCV 默认用 BGR 顺序,而大多数图像处理库(如 matplotlib、PIL)用 RGB。你想想看,如果不转换,显示出来的图像颜色完全不对。
转换函数是 cv2.cvtColor():
# BGR 转 RGB
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# BGR 转灰度
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# RGB 转 BGR(反向转换)
img_bgr = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2BGR)
核心要点:YOLO 推理时,模型通常要求输入 RGB 图像。但 OpenCV 读取的是 BGR。所以你在送入模型前,必须做一次 BGR→RGB 转换。我见过有人忘了这步,模型精度直接掉一半。
灰度转换的原理是加权平均:Gray = 0.299*R + 0.587*G + 0.114*B。OpenCV 内部已经优化好了,直接用就行。
| 转换代码 | 用途 |
|---|---|
cv2.COLOR_BGR2RGB |
BGR → RGB,用于正确显示或送入深度学习模型 |
cv2.COLOR_BGR2GRAY |
BGR → 灰度,用于边缘检测、特征提取等 |
cv2.COLOR_GRAY2BGR |
灰度 → BGR,将单通道复制为三通道 |
cv2.COLOR_BGR2HSV |
BGR → HSV,用于颜色分割、目标跟踪 |
2.4 实战:图像读取与色彩空间转换流程
下面我把整个流程串起来,写一个完整的示例。这也是我平时调试图像处理管线的标准模板。
import cv2
import numpy as np
# 1. 读取图像
img_bgr = cv2.imread('test.jpg')
if img_bgr is None:
print("图像读取失败")
exit()
# 2. 显示原始 BGR 图像
cv2.imshow('Original BGR', img_bgr)
# 3. 转换为 RGB
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
# 4. 转换为灰度
img_gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)
# 5. 显示结果
cv2.imshow('RGB', img_rgb)
cv2.imshow('Gray', img_gray)
# 6. 保存灰度图
cv2.imwrite('gray_output.jpg', img_gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
避坑指南:如果你用 Jupyter Notebook,
cv2.imshow() 可能会崩溃。我建议用 matplotlib 的 imshow() 来显示,但记得先转成 RGB。或者直接用 cv2_imshow()(Google Colab 专用)。
2.5 知识体系:图像基础操作流程
下面这张图概括了本章的核心逻辑。你看一遍就能记住整个流程。
2.6 本章小结
- imread:默认 BGR,路径别带中文,记得判空。
- imshow + waitKey:成对出现,否则窗口卡死。
- imwrite:保存的是 BGR 顺序,用 matplotlib 显示前要转 RGB。
- cvtColor:BGR→RGB 是 YOLO 推理前的必备步骤。
说白了,这一章就是给后面所有章节打地基。你把这些基础操作练熟了,后面做帧处理、做推理加速才不会手忙脚乱。我当年刚学 OpenCV 时,光 BGR 和 RGB 的坑就踩了不下十次。你现在记住,后面就省心了。