图像预处理基础:色彩空间转换、图像滤波与去噪、直方图均衡化
各位同学,大家好。今天我们聊点真正干活的东西——图像预处理。
说实话,很多刚入行的同学觉得预处理就是“调参数”,随便搞搞就行。但我得告诉你,在真实的自动驾驶项目里,预处理做得好不好,直接决定了后面车道线检测的成败。我见过太多项目,模型结构改来改去效果上不去,最后发现是预处理环节出了问题。
好,我们直接进入正题。
一、色彩空间转换:为什么非转不可?
摄像头拍出来的原始图像,通常是RGB格式。但RGB有个问题——它对光照变化特别敏感。你想想看,白天和傍晚,同样的车道线,RGB三个通道的值可能差好几倍。
我个人习惯,在做车道线检测之前,先把图像转到HSV或YUV色彩空间。为什么?因为这两个空间把亮度信息和颜色信息分开了。
- HSV:H(色调)、S(饱和度)、V(明度)。车道线的颜色信息主要在H和S通道,而光照变化主要在V通道。我们可以在V通道做处理,不影响颜色信息。
- YUV:Y(亮度)、U和V(色度)。Y通道基本就是灰度图,适合做边缘检测。U和V通道包含颜色信息,适合做颜色分割。
举个例子,在OpenCV里转换很简单:
import cv2
# 读取图像
img = cv2.imread('road.jpg')
# RGB转HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# RGB转YUV
yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
二、图像滤波与去噪:别让噪声毁了你的边缘
摄像头传感器本身就有噪声,再加上路面颠簸、光线变化,原始图像里全是“毛刺”。如果不做滤波,后面提取边缘时,你会得到一堆假边缘。
常用的滤波方法有几种,我按使用频率排个序:
| 滤波方法 | 特点 | 我的使用场景 |
|---|---|---|
| 高斯滤波 | 平滑效果好,保留边缘 | 白天正常光照,最常用 |
| 中值滤波 | 对椒盐噪声效果极好 | 夜间或雨雪天气,传感器噪声大 |
| 双边滤波 | 保边去噪,但速度慢 | 需要保留车道线细节时用 |
代码实现也很直接:
import cv2
img = cv2.imread('road.jpg')
# 高斯滤波,核大小5x5
gaussian = cv2.GaussianBlur(img, (5, 5), 0)
# 中值滤波,核大小5
median = cv2.medianBlur(img, 5)
# 双边滤波,d=9, sigmaColor=75, sigmaSpace=75
bilateral = cv2.bilateralFilter(img, 9, 75, 75)
三、直方图均衡化:让暗处的车道线“亮”起来
你有没有遇到过这种情况?车子开进隧道,图像突然变暗,车道线几乎看不见。或者逆光行驶,路面一片白茫茫。
这时候就需要直方图均衡化出手了。它的原理很简单:把图像的灰度分布“拉伸”开,让暗的地方变亮,亮的地方变暗,整体对比度提升。
我常用的有两种方式:
- 全局直方图均衡化:对整个图像做均衡。简单粗暴,但有时会过度增强噪声。
- 自适应直方图均衡化(CLAHE):把图像分成小块,每块分别做均衡。效果更自然,不会出现“过曝”感。
看代码:
import cv2
# 读取灰度图
gray = cv2.imread('road.jpg', 0)
# 全局直方图均衡化
equalized = cv2.equalizeHist(gray)
# CLAHE自适应均衡化
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
clahe_result = clahe.apply(gray)
重点来了:在车道线检测中,我强烈建议使用CLAHE。全局均衡化会把路面纹理也增强,导致很多假边缘。而CLAHE只增强局部对比度,车道线更清晰,噪声更少。
嗯,这里要注意一点:直方图均衡化最好在亮度通道上做。如果你用的是HSV空间,就在V通道做;如果是YUV,就在Y通道做。不要在RGB三个通道分别做,那样会破坏颜色平衡,出来的图像颜色会很奇怪。
四、本章知识体系总览
为了让你更直观地理解这三个预处理步骤的关系,我画了一张流程图:
你看,这三个步骤是有顺序的。先转色彩空间,把亮度和颜色分开;然后滤波去噪,把传感器噪声和路面纹理噪声去掉;最后做直方图均衡化,提升对比度。顺序不能乱,否则效果会打折扣。
好了,图像预处理的基础就讲到这里。这些内容看似简单,但每一个细节都值得你反复推敲。下次遇到车道线检测效果不好,先别急着改模型,回头看看预处理是不是出了问题。