2. 图像基础与OpenCV入门:图像表示、颜色空间、OpenCV核心操作

各位同学,欢迎来到第二章。这一章咱们要聊的是自动驾驶视觉感知的「地基」——图像本身。你想想看,不管后面用多牛的深度学习模型,输入终究是一张张图像。如果连图像怎么存、怎么读、怎么转都搞不清楚,后面调参调得再欢也是空中楼阁。

我个人习惯,在开始任何项目之前,先把数据「摸」一遍。摸数据的第一步,就是搞懂图像在计算机里到底长什么样。好,咱们直接开干。

2.1 图像在计算机里是怎么表示的?

说白了,一张数字图像就是一个巨大的二维矩阵。对于灰度图,每个像素就是一个0到255的数值,0代表纯黑,255代表纯白。对于彩色图,每个像素由三个通道组成——红、绿、蓝,也就是我们常说的RGB。

举个例子,一张640×480的彩色图像,在内存里就是一个480行、640列、3层深度的三维数组。形状是 (480, 640, 3)。嗯,这里要注意:OpenCV里通道顺序是BGR,不是RGB。我第一次用OpenCV读图显示出来颜色怪怪的,查了半天才发现是通道顺序搞反了。这个坑,我替你们踩过了。

核心概念:
  • 像素:图像的最小单元,一个点
  • 分辨率:宽度×高度,比如1920×1080
  • 通道:灰度图1通道,彩色图3通道(BGR)
  • 位深:通常8位,即0-255

2.2 颜色空间:不只是RGB

RGB虽然直观,但在自动驾驶场景里并不总是最好用的。为什么?因为RGB三个通道高度相关,光照一变,三个值一起变,很难做阈值分割。

我建议你重点掌握以下三种颜色空间:

颜色空间 特点 自动驾驶中的应用
RGB / BGR 最原始,硬件直接输出 模型输入、显示
HSV 色调、饱和度、明度分离 车道线检测、交通灯识别
灰度 单通道,计算量小 边缘检测、特征匹配

我在做车道线检测项目时,就吃过RGB的亏。白天阳光强烈,黄色车道线在RGB下跟路面混在一起,阈值怎么调都不对。后来换成HSV空间,只对色调通道做阈值分割,效果立竿见影。说白了,选对颜色空间,比调参重要十倍。

小技巧:在HSV中,H(色调)范围是0-179,S和V是0-255。OpenCV的HSV范围跟其他库不一样,别搞混了。

2.3 OpenCV核心操作:读取、显示、保存

好,理论讲完了,咱们直接上代码。OpenCV的安装很简单,pip install opencv-python 就行。我个人习惯用cv2这个别名,简洁明了。

2.3.1 读取图像

import cv2

# 读取图像,默认是彩色模式(BGR)
img = cv2.imread('road.jpg')

# 读取为灰度图
img_gray = cv2.imread('road.jpg', cv2.IMREAD_GRAYSCALE)

# 检查是否读取成功
if img is None:
    print("图像读取失败,检查路径!")

这里有个坑:imread如果路径不对,不会报错,而是返回None。我曾经在调试时花了半小时找bug,最后发现是文件名多打了一个空格。嗯,这种低级错误,谁还没犯过呢?

2.3.2 显示图像

# 显示图像
cv2.imshow('My Window', img)

# 等待按键,0表示无限等待
cv2.waitKey(0)

# 关闭所有窗口
cv2.destroyAllWindows()

注意:waitKey的参数单位是毫秒。如果你不调用waitKey,窗口会一闪而过。我刚开始学的时候,窗口闪一下就没了,还以为代码写错了。

2.3.3 保存图像

# 保存为PNG格式
cv2.imwrite('output.png', img)

# 保存为JPEG,第三个参数控制质量(0-100)
cv2.imwrite('output.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, 95])
避坑指南:我曾经在保存图像时,直接覆盖了原始文件,结果原始数据丢了。建议养成好习惯:读入时用只读模式,保存时另存为新文件,不要原地覆盖。

2.4 实战小练习:图像通道分离与合并

咱们来个小练习,把一张彩色图的三个通道分开看看:

import cv2
import numpy as np

img = cv2.imread('car.jpg')
b, g, r = cv2.split(img)

# 创建一个全黑通道
zeros = np.zeros_like(b)

# 只保留红色通道
red_only = cv2.merge([zeros, zeros, r])

cv2.imshow('Red Channel', red_only)
cv2.waitKey(0)
cv2.destroyAllWindows()

你运行一下就会发现,红色通道里,原本红色的车灯特别亮,蓝色的天空几乎全黑。这就是通道分离的魅力——你可以直观地看到每个通道对图像的贡献。

2.5 本章小结

这一章咱们把图像的基础打牢了。你学会了:

  • 图像本质上是多维数组
  • BGR和HSV各有各的适用场景
  • OpenCV的三大核心操作:读、显、存
  • 通道分离与合并的基本用法

下一章,咱们要进入图像预处理的世界。说白了,就是给图像「洗个澡」,让它更适合后续的算法处理。到时候我会分享一些我在实际项目中用到的预处理技巧,保证实用。

好,今天的课就到这里。记得动手敲代码,光看是学不会的。咱们下章见。