1. 图像处理基础

各位同学好,欢迎来到《图像处理算法优化与摄像头调优》的第一章。

说实话,我见过太多人一上来就调算法、跑模型,结果连一张图片在内存里长什么样都说不清楚。这就像盖楼不打地基——迟早要塌。今天咱们就把这块地基夯实了。

1.1 像素——图像的最小单元

一张数字图像,说白了就是一个二维数组。数组里的每个元素,就是一个像素。

我习惯把像素想象成马赛克瓷砖。你离远了看,是一幅完整的画;凑近了看,就是一个个小方块。每个小方块都有自己的颜色值。

核心概念:像素是图像的基本采样单元。每个像素存储一个数值(灰度图)或一组数值(彩色图),代表该位置的亮度或颜色信息。

举个例子,一张 640×480 的灰度图,就是 640 列、480 行的矩阵。每个格子存一个 0~255 的整数,0 代表纯黑,255 代表纯白。就这么简单。

我的经验:做嵌入式视觉时,我经常把图像分辨率记成「宽×高×通道数」。比如 640×480×3 就是一张彩色图。这个习惯帮我避免了很多内存越界的坑。

1.2 色彩空间——计算机怎么「看」颜色

人眼感知颜色靠的是三种视锥细胞。计算机呢?它靠的是色彩空间模型。

1.2.1 RGB 色彩空间

最常用的就是 RGB。红、绿、蓝三个通道,每个通道 0~255,组合出 1600 多万种颜色。显示器、摄像头传感器,基本都是 RGB 的天下。

但 RGB 有个问题——它跟人眼的感知方式不太匹配。你调高红色分量,人眼感觉到的亮度变化并不线性。这就引出了下一个模型。

1.2.2 YUV / YCbCr 色彩空间

YUV 把亮度(Y)和色度(U、V)分开。这个设计很聪明——人眼对亮度敏感,对颜色不敏感。所以视频压缩时可以多保留 Y 的信息,少保留 UV 的信息,画质损失不大。

我记得第一次做摄像头驱动时,发现采集到的数据是 YUYV 格式,直接当 RGB 显示,颜色全乱套了。嗯,从那以后我再也不敢忽略色彩空间转换了。

1.2.3 HSV 色彩空间

HSV 把颜色拆成色调(H)、饱和度(S)、明度(V)。做颜色识别时特别好用——你想找红色物体,直接限定 H 的范围就行,不受光照变化影响。

色彩空间 通道含义 典型应用 我的建议
RGB 红、绿、蓝 显示、传感器原始数据 做显示用,做分析别用
YUV/YCbCr 亮度、蓝色差、红色差 视频编码、摄像头输出 嵌入式摄像头默认格式
HSV 色调、饱和度、明度 颜色识别、图像分割 颜色检测首选
灰度 单通道亮度 边缘检测、二值化 省内存、速度快

1.3 图像数字化与存储格式

模拟信号怎么变成数字图像?这个过程叫数字化,包含两步:采样和量化。

  • 空间采样:决定图像的分辨率。采样越密,细节越多,文件也越大。
  • 幅度量化:决定每个像素的位深。8 位就是 256 级灰度,10 位就是 1024 级。

你想想看,一张 12 位深度的 RAW 图,比 8 位的 JPEG 包含更多细节。但代价是文件体积翻倍。这就是为什么专业相机拍 RAW,手机默认拍 JPEG——存储和画质的取舍。

1.3.1 常见图像存储格式

格式 压缩方式 特点 适用场景
BMP 无压缩 文件大,读取快 学习调试用
JPEG 有损压缩 文件小,有块效应 网络传输、存储
PNG 无损压缩 支持透明通道 UI、图标、需要保真的场景
RAW 传感器原始数据 未处理,位深高 专业摄影、ISP 调试

避坑指南:我曾经在项目中直接用 JPEG 做边缘检测,结果压缩带来的块效应导致检测结果全是假边缘。后来换成 PNG 或 BMP 就正常了。记住——有损压缩会破坏像素的原始关系,做图像分析时尽量用无损格式。

1.4 知识体系总览

下面这张图把本章的核心知识点串起来了。你可以把它当作整个课程的「地图」——后面每一章都会在这张图上展开。

图像处理基础 - 知识体系 图像处理基础 - 知识体系 图像处理基础 像素与色彩空间 图像数字化与存储 OpenCV环境与操作 像素概念 RGB / YUV / HSV 采样与量化 BMP/JPEG/PNG 环境搭建 读写显示 imread / imwrite imshow / waitKey 💡 学习路径:先理解像素 → 再掌握色彩空间 → 然后学会读写图像 → 最后用 OpenCV 把前面学的知识串起来

1.5 OpenCV 环境搭建与基本操作

理论说完了,咱们来点实际的。OpenCV 是图像处理领域最常用的库,没有之一。我这些年做过的项目,从手机摄像头调优到工业检测,几乎都离不开它。

1.5.1 安装 OpenCV

Python 环境下,安装就一行命令:

pip install opencv-python opencv-contrib-python

如果你用 C++,建议从源码编译,这样能开启优化选项。我个人习惯在 Linux 下编译时加上 -DCMAKE_BUILD_TYPE=RELEASE 和 -DWITH_TBB=ON,速度能快不少。

小技巧:安装后运行 python -c "import cv2; print(cv2.__version__)" 验证。如果看到版本号,说明装好了。

1.5.2 读取、显示、保存图像

这是 OpenCV 最基础的三板斧。看代码:

import cv2

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

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

# 保存图像
cv2.imwrite('output.jpg', img)

这里有个坑——imread 默认以 BGR 顺序读取,不是 RGB。我第一次用 OpenCV 时,用 matplotlib 显示图像,颜色全偏蓝。后来才反应过来,OpenCV 的默认色彩空间是 BGR。

重要提醒:OpenCV 使用 BGR 顺序!如果你用其他库(如 matplotlib)显示,记得先转换:img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)。

1.5.3 访问和修改像素

图像在 OpenCV 里就是 NumPy 数组。访问像素就像操作矩阵:

import cv2
import numpy as np

# 创建一个 300x300 的红色图像
img = np.zeros((300, 300, 3), dtype=np.uint8)
img[:, :] = (0, 0, 255)  # BGR 顺序,所以 (0,0,255) 是红色

# 访问 (100, 100) 处的像素
(b, g, r) = img[100, 100]
print(f"B:{b}, G:{g}, R:{r}")

# 修改某个区域
img[50:150, 50:150] = (255, 0, 0)  # 蓝色方块

你想想看,掌握了像素级别的操作,后面做滤波、边缘检测、形态学处理,其实都是在操作这些数值。

1.5.4 色彩空间转换

前面讲了那么多色彩空间,现在用代码实现一下:

import cv2

img = cv2.imread('lena.jpg')

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

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

# 转 YUV
yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)

做颜色识别时,我几乎只用 HSV。比如检测红色:

import cv2
import numpy as np

img = cv2.imread('red_ball.jpg')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# 红色在 HSV 中的范围
lower_red = np.array([0, 50, 50])
upper_red = np.array([10, 255, 255])
mask = cv2.inRange(hsv, lower_red, upper_red)

cv2.imshow('Red Mask', mask)
cv2.waitKey(0)

核心要点:色彩空间转换是图像预处理的第一步。选对色彩空间,后续处理事半功倍。做检测用 HSV,做压缩用 YUV,做显示用 RGB——这是铁律。

1.6 本章小结

这一章我们走完了图像处理的「第一公里」:

  • 理解了像素是图像的基本单元
  • 掌握了RGB、YUV、HSV三种色彩空间的特点和用途
  • 明白了数字化的两个关键步骤:采样和量化
  • 区分了BMP、JPEG、PNG、RAW等存储格式的适用场景
  • 搭建了OpenCV环境,学会了读写显示和像素操作

这些基础看似简单,但我在实际项目中见过太多人在这里栽跟头。色彩空间搞错、像素位深忽略、格式选错——每一个都是实打实的 bug。希望你能把这些基础打牢,后面的路会顺畅很多。