第1章:图像处理基础:OpenCV入门、图像读取与显示、色彩空间转换、图像几何变换

1.1 为什么从OpenCV开始?

做交通标志检测,说白了就是跟图像打交道。你想想看,摄像头拍下来的每一帧画面,都是数字图像。而OpenCV,就是处理这些图像最趁手的工具。

我个人习惯,不管做什么视觉项目,第一件事就是把OpenCV装好。它就像一个瑞士军刀——功能多、速度快、社区活跃。我在做自动驾驶项目时,90%的图像预处理工作都是用OpenCV完成的。

1.2 安装与第一行代码

安装很简单,一行命令搞定:

pip install opencv-python

嗯,这里要注意。如果你需要用到一些高级功能(比如SIFT特征提取),建议装完整版:

pip install opencv-contrib-python

装完之后,我们来写第一行代码。我习惯先验证一下版本:

import cv2
print(cv2.__version__)

看到版本号输出来,说明环境没问题了。

1.3 图像读取与显示

读取图像用 imread(),显示用 imshow()。这两个函数,你以后会天天用。

import cv2

# 读取图像
img = cv2.imread('traffic_sign.jpg')

# 显示图像
cv2.imshow('Traffic Sign', img)
cv2.waitKey(0)          # 等待按键
cv2.destroyAllWindows() # 关闭窗口

我曾经踩过一个坑:图像路径不能有中文!OpenCV的imread()对中文路径支持不好,读出来是None。后来我所有项目文件都用英文命名,再也没出过问题。

还有一个细节:imread()默认以BGR格式读取。这和常见的RGB顺序不一样。很多初学者在这里翻车,图像颜色看起来怪怪的。

1.4 色彩空间转换

为什么要做色彩空间转换?因为交通标志的颜色信息太重要了。红色禁令标志、蓝色指示标志、黄色警告标志——颜色就是第一道筛选器。

OpenCV提供了 cvtColor() 函数,可以轻松转换色彩空间:

# BGR 转灰度
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# BGR 转 HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# BGR 转 RGB
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

我个人最常用的是HSV空间。为什么?因为HSV把颜色(Hue)和亮度(Saturation、Value)分开了。在项目中,我经常用HSV做颜色阈值分割,效果比BGR好得多。

实战经验:红色交通标志在HSV中的H值大约在0-10和170-180两个区间。因为红色在色环上是首尾相接的。我第一次做红色检测时只设了0-10,结果漏掉了一半红色区域。后来才意识到要处理两个区间。

1.5 图像几何变换

摄像头拍到的交通标志,角度、大小、位置都不一样。几何变换就是用来解决这些问题的。

1.5.1 缩放

# 缩小到原来的一半
small = cv2.resize(img, None, fx=0.5, fy=0.5)

# 指定目标尺寸
resized = cv2.resize(img, (200, 200))

缩放时有个插值方法的选择。缩小用 INTER_AREA,放大用 INTER_LINEARINTER_CUBIC。这是我在项目中试出来的经验。

1.5.2 旋转

# 获取图像尺寸
h, w = img.shape[:2]

# 计算旋转矩阵(顺时针45度)
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, -45, 1.0)

# 执行旋转
rotated = cv2.warpAffine(img, M, (w, h))

你想想看,路边的交通标志经常是歪的。旋转校正后,识别准确率能提升不少。

1.5.3 平移与仿射变换

# 平移
M_trans = np.float32([[1, 0, 50], [0, 1, 30]])
translated = cv2.warpAffine(img, M_trans, (w, h))

# 仿射变换(三个点对应)
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])
M_affine = cv2.getAffineTransform(pts1, pts2)
affined = cv2.warpAffine(img, M_affine, (w, h))

小技巧:做数据增强时,我经常用仿射变换来生成更多训练样本。轻微旋转、缩放、平移,能让模型泛化能力更强。但注意不要变换得太夸张,否则标志都认不出来了。

1.6 本章小结

这一章我们学了OpenCV的四个基本功:

  • 图像读取与显示:imread、imshow、waitKey
  • 色彩空间转换:BGR、灰度、HSV,以及为什么HSV更适合颜色检测
  • 图像缩放:resize函数和插值方法的选择
  • 几何变换:旋转、平移、仿射变换,以及它们在交通标志检测中的应用

这些基础操作,在后续的交通标志检测项目中会反复用到。我建议你多动手敲代码,把每个函数都跑一遍。看十遍不如写一遍,这是我一直以来的习惯。

下一章,我们会进入图像预处理的核心——滤波、边缘检测和形态学操作。这些技术能帮我们从图像中提取出交通标志的轮廓。准备好了吗?