3、图像处理基础:像素、分辨率、颜色空间(RGB、灰度、HSV)、图像坐标系、图像存储格式
在开始OpenMV项目开发之前,必须建立对图像数据底层逻辑的清晰认知。无论是颜色识别、二维码检测还是神经网络分类,所有视觉算法的输入都是像素矩阵。本章将系统拆解像素与分辨率的关系、RGB/灰度/HSV三种颜色空间的数学定义与适用场景、图像坐标系的方向约定,以及OpenMV中常见的图像存储格式。理解这些基础概念,将直接决定你在编写阈值脚本、调试识别参数时的效率与准确性。
3.1 像素与分辨率:图像的最小单元与尺寸度量
核心原理
像素(Pixel)是数字图像的最小采样单元,每个像素对应传感器感光阵列上的一个物理感光点。分辨率则定义为图像在水平与垂直方向上的像素数量,通常写作宽度×高度(如640×480)。OpenMV Cam H7 Plus默认使用640×480的OV5640传感器,在QVGA模式(320×240)下帧率可提升至更高水平。分辨率直接影响两个关键指标:空间细节保留能力与处理带宽消耗。高分辨率意味着更多像素需要被CPU或硬件加速器处理,导致帧率下降;低分辨率则可能丢失小目标特征。
判断方法与操作流程
在OpenMV中,通过sensor.set_windowing()或sensor.set_framesize()设置分辨率。选择分辨率时需遵循以下流程:
- 明确检测目标尺寸:若目标在画面中占比小于5%,应优先保证分辨率;若目标较大且需要高速响应,则降低分辨率。
- 评估处理复杂度:颜色识别对分辨率不敏感,可选用QQVGA(160×120);二维码识别需要至少能覆盖码区30×30像素,建议QVGA以上。
- 测试帧率:使用
clock.fps()监控实际帧率,确保不低于应用需求(如10FPS)。
案例拆解:二维码检测的分辨率选择
假设需要识别距离30cm处的QR码(码区尺寸约5cm×5cm)。在640×480分辨率下,码区约占120×120像素,识别稳定;若降至QVGA(320×240),码区仅占60×60像素,仍可识别但抗畸变能力下降。实际测试中,QVGA下帧率从25FPS提升至45FPS,但误码率从0.3%升至1.2%。最终方案:采用QVGA+2倍数字变焦(sensor.set_windowing()裁剪中心区域),既保证码区像素密度,又控制处理负载。
常见误区与总结
- 误区1:认为分辨率越高越好。实际上,OpenMV的CPU(STM32H7)在640×480下运行颜色识别仅能达到15FPS,而QVGA下可达30FPS以上。
- 误区2:忽略分辨率对镜头视场角的影响。相同焦距下,分辨率降低不会改变视场角,但会降低单位角度内的像素密度。
| 分辨率模式 | 尺寸(像素) | 单帧RGB565大小 | 典型应用场景 |
|---|---|---|---|
| QQVGA | 160×120 | 38.4KB | 高速颜色追踪、帧率优先 |
| QVGA | 320×240 | 153.6KB | 通用视觉任务、平衡帧率与细节 |
| VGA | 640×480 | 614.4KB | 静态图像采集、高精度检测 |
| B64X64 | 64×64 | 8KB | 神经网络输入、极高速处理 |
3.2 颜色空间:RGB、灰度与HSV的数学本质与转换逻辑
核心原理
颜色空间是描述颜色的数学模型。OpenMV默认输出RGB565格式(5位R、6位G、5位B),但算法处理时通常转换为其他空间:
- RGB空间:基于人眼感光细胞的三刺激理论,R(红)、G(绿)、B(蓝)三个通道叠加产生颜色。RGB适合显示,但对光照变化敏感——同一物体在不同亮度下RGB值波动极大。
- 灰度空间:将RGB按亮度公式
Y = 0.299R + 0.587G + 0.114B加权求和,得到单通道亮度值(0-255)。灰度保留了形状和纹理信息,丢弃了色度信息,适合边缘检测、模板匹配。 - HSV空间:H(色相,0-179)、S(饱和度,0-255)、V(明度,0-255)。HSV将颜色与亮度分离,H通道对光照变化不敏感,是颜色识别的首选空间。OpenMV的
find_blobs()函数默认使用LAB空间,但LAB与HSV在色相分离逻辑上相似。
转换方法与操作流程
OpenMV中通过image.to_rgb()、image.to_grayscale()、image.to_hsv()进行转换。实际开发中,颜色阈值通常在IDE的阈值编辑器中调整,该工具实时显示LAB/HSV各通道的直方图。操作流程:
- 拍摄目标物体的静态图像,确保光照均匀。
- 在IDE中打开阈值编辑器,选择HSV或LAB模式。
- 框选目标区域,观察各通道的像素值分布范围。
- 设置最小/最大阈值,测试不同光照下的鲁棒性。
案例拆解:多颜色物体分拣中的颜色空间选择
某分拣项目需区分红、绿、蓝三色积木。使用RGB阈值时,由于环境光从侧面照射,积木表面产生高光,导致R通道值波动超过±40,误检率高达15%。改用HSV后,固定H通道阈值(红:0-10,绿:40-80,蓝:100-130),S阈值设为80-255,V阈值设为50-255,误检率降至0.5%。关键步骤:
- 采集20张不同光照下的样本图像,统计H通道的均值和标准差。
- 将阈值范围设为均值±3倍标准差,确保覆盖极端情况。
- 在代码中动态调整V通道下限,适应早晚光照变化。
常见误区与总结
- 误区1:直接使用RGB阈值进行颜色识别。RGB三个通道高度相关,光照变化会同时影响三个值,导致阈值难以收敛。
- 误区2:忽略HSV中H通道的环形特性。红色在H通道中同时位于0附近和179附近,需设置两个区间并合并。
- 误区3:灰度图像无法进行颜色识别。灰度仅保留亮度信息,但可通过灰度差检测特定颜色(如深色物体在浅色背景上),适用于对比度明显的场景。
3.3 图像坐标系:从像素矩阵到空间位置的映射
核心原理
OpenMV遵循OpenCV的坐标系约定:原点(0,0)位于图像左上角,x轴向右为正方向(列方向),y轴向下为正方向(行方向)。这与数学中常见的笛卡尔坐标系(y轴向上)不同,容易造成混淆。在find_blobs()返回的blob对象中,cx()和cy()分别表示色块中心的x和y坐标,单位是像素。
判断方法与操作流程
当需要将像素坐标转换为实际物理位置时,需考虑相机标定参数(焦距、畸变系数)。OpenMV提供image.lens_corr()进行畸变校正,但基础项目中通常直接使用像素坐标。操作流程:
- 获取目标中心坐标
(cx, cy)。 - 计算与图像中心
(width/2, height/2)的偏移量。 - 根据偏移量控制云台或电机进行跟踪。
set_windowing()裁剪了图像区域,坐标系原点会变为裁剪区域的左上角,而非整个传感器画面的左上角。务必确认当前帧的实际尺寸。
案例拆解:基于坐标偏移的云台跟踪
项目要求云台跟踪红色小球。初始现象:小球在画面左侧时,云台向左转动,但转动速度恒定导致过冲。分析:直接使用cx与中心点的差值作为速度输入,但未考虑差值大小与角速度的非线性关系。改进方案:
- 将偏移量归一化:
error_x = (cx - width/2) / (width/2),范围-1到1。 - 使用比例控制:
servo_speed = Kp * error_x,Kp=0.3。 - 加入死区:当
abs(error_x) < 0.05时,停止转动,避免抖动。
结果:跟踪响应时间从1.2秒缩短至0.4秒,过冲量减少70%。
常见误区与总结
- 误区1:混淆行列与xy。在
img.get_pixel(x, y)中,x是列索引,y是行索引,与数组访问array[y][x]顺序相反。 - 误区2:忽略图像翻转。若传感器安装角度为倒置,需使用
sensor.set_vflip()和sensor.set_hmirror()校正,否则坐标方向与实际空间方向不一致。
3.4 图像存储格式:BMP、JPEG、PNG与RAW的选择策略
核心原理
OpenMV支持多种图像存储格式,不同格式在压缩率、质量、解码速度上差异显著:
- BMP:无压缩,每个像素按RGB565或RGB888存储,文件体积大,但读写速度快,适合临时存储或需要逐像素处理的场景。
- JPEG:有损压缩,压缩率高(通常10:1以上),但解码需要额外CPU开销,且压缩会产生块效应,影响边缘检测精度。
- PNG:无损压缩,支持透明度,但压缩速度慢,OpenMV上较少使用。
- RAW:传感器原始数据,未经过ISP处理,保留最多信息,但文件极大且需要额外处理。
判断方法与操作流程
选择存储格式时,需权衡以下因素:
- 存储介质:SD卡容量与写入速度。JPEG每秒可写入约5帧(640×480),BMP仅1帧。
- 后续处理:若需在PC端进行精确测量,应使用BMP或PNG;若仅用于记录或传输,JPEG足够。
- 实时性:JPEG编码占用CPU时间,会降低帧率。实测OpenMV H7 Plus在640×480下,JPEG编码耗时约80ms,而BMP直接内存拷贝仅需5ms。
img.save("/sd/capture.jpg", quality=80)。quality参数控制压缩质量,80在视觉上与原始图像几乎无差异,但文件体积比quality=100减小约40%。
案例拆解:远程监控系统的图像传输格式优化
项目通过WiFi将OpenMV采集的图像发送至PC端显示。初始方案:使用BMP格式,每帧614KB,传输延迟约2秒。优化方案:改用JPEG格式,quality=70,每帧约45KB,延迟降至150ms。但发现图像中文字边缘出现模糊,影响人工判读。进一步优化:对图像中心区域(ROI)使用quality=90,边缘区域使用quality=60,通过img.copy(roi=...)分别压缩后拼接。最终在保持关键区域清晰度的同时,平均帧大小控制在60KB,延迟200ms,满足实时监控需求。
常见误区与总结
- 误区1:认为JPEG质量参数越高越好。quality=95以上时,文件体积急剧增大但视觉提升不明显,且编码时间翻倍。
- 误区2:忽略SD卡写入速度瓶颈。低速SD卡在连续写入JPEG时可能丢帧,应使用Class 10或UHS-I级别卡。
- 误区3:在内存中频繁创建大尺寸图像对象。OpenMV的GC(垃圾回收)机制在内存紧张时会暂停程序,应尽量复用图像缓冲区。
| 格式 | 压缩类型 | 640×480典型大小 | 编码耗时 | 适用场景 |
|---|---|---|---|---|
| BMP | 无 | 614KB | 5ms | 逐像素处理、临时存储 |
| JPEG | 有损 | 40-80KB | 80ms | 网络传输、SD卡记录 |
| PNG | 无损 | 300-500KB | 200ms | 需要透明通道或无损需求 |
| RAW | 无 | 1.2MB | 1ms | 专业图像分析、ISP调试 |