📑 本文导航
简介
适合比赛现场翻看,所有核心要点、API、故障排查、通信协议,精简汇总,OpenMV4‑H7 R2 为主。

一、硬件速查
引脚(UART 最重要)
- UART1:P4 (TX)、P5 (RX)【默认使用】
- UART2:P1(TX)、P0(RX)
- 电平:全部 IO 3.3V 输出,支持 5V 输入耐压,不能输出 5V
- 接线铁律:OpenMV‑TX → STM32‑RX;OpenMV‑RX → STM32‑TX;GND 必须互连(共地),否则必乱码
- 供电:USB5V / 3.7V 锂电池;严禁超过 5V
- 镜头:
- H7‑R2:MT9M114 全局快门,运动无拖影,竞赛首选
- H7‑Plus:OV5640 卷帘快门,高速运动物体倾斜扭曲
摄像头初始化必写(颜色识别必关自动增益白平衡)
python
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA) #320*240,竞赛首选分辨率
sensor.skip_frames(2000)
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)
clock = time.clock()
二、核心 API 速查表
1. 色块识别 find_blobs(循迹、颜色分拣)
python
blobs = img.find_blobs([threshold],roi=(x,y,w,h),pixels_threshold=20,area_threshold=20,merge=True)
- roi:感兴趣区域,只处理画面局部,提升速度最重要手段
- pixels_threshold /area_threshold:过滤噪点小色块
- 返回 blob 对象常用成员:
- blob.cx () 中心 X (0‑319);blob.cy () 中心 Y (0‑239)
- blob.rect () 矩形框 (x,y,w,h)
- blob.pixels () 色块像素面积
HSV 阈值获取:IDE 工具 → 机器视觉阈值编辑器。 格式:(Lmin,Lmax,Amin,Amax,Bmin,Bmax)
2.AprilTag 识别
python
tags = img.find_apriltags(fx=f_x,fy=f_y,cx=c_x,cy=c_y)
tag 成员:
- tag.id () 标签 ID
- tag.x_translation () /y_translation () /z_translation () 平移,单位米
- tag.rotation () 旋转角度
⚠️更换镜头必须修改 fx fy cx cy 内参,否则距离完全不准! 使用标签家族 36h11。
3.QR 二维码
python
codes = img.find_qrcodes()
codes[0].payload() #获取字符串
4.FOMO AI 目标检测
python
net = tf.load("/trained.tflite",load_to_fb=True)
for obj in net.classify(img,roi=True):
obj.cx(),obj.cy(),obj.classid(),obj.score()
置信度建议阈值 0.5‑0.7;H7 不要用大模型,容易内存溢出死机。
5. 绘图调试(仅 IDE 可视化,不影响识别)
python
img.draw_rectangle(rect)
img.draw_cross(cx,cy)
三、三套标准串口通信报文(直接复制使用,波特率 115200,8‑N‑1)
帧结束标记\r\n,单片机依靠\n判断一帧接收完毕
1)颜色色块报文:
B,cx,cy\r\n;无目标 B,-1,-1\r\n 2)AprilTag 报文:TAG,id,tx,ty,tz\r\n;无标签 TAG,-1,0.00,0.00,0.00\r\n 3)FOMO 报文:F,class_id,cx,cy,score\r\nOpenMV 发送示例:
python
运行
uart = pyb.UART(1,115200)
uart.write("B,%d,%d\r\n"%(cx,cy))
STM32 解析要点
- 串口中断逐字节接收,检测
\n代表一帧结束 - 使用
sscanf解析字符串 - 解析失败直接丢弃本帧,不要使用旧数据
四、STM32 通用工具代码片段
1. 滑动平均滤波,抑制识别跳变
c
#define FILTER_LEN 5
int16_t buf[FILTER_LEN];
uint8_t idx=0;
int16_t filter(int16_t new_val)
{
buf[idx++]=new_val;
if(idx>=FILTER_LEN) idx=0;
int sum=0;
for(int i=0;i<FILTER_LEN;i++) sum+=buf[i];
return sum/FILTER_LEN;
}
2. 简单 PID 位置闭环模板
c
//err = 目标值 - 当前值
float Kp=0.35,Ki=0.0,Kd=0.1;
int error,last_error;
float integral;
float pid_calc(int err)
{
error = err;
integral += error;
float diff = error - last_error;
float out = Kp*error + Ki*integral + Kd*diff;
last_error = error;
return out;
}
3.constrain 限幅函数
c
int constrain(int val,int min,int max)
{
if(val<min) return min;
if(val>max) return max;
return val;
}
五、比赛高频问题快速定位
| 现象 | 大概率原因 | 解决方法 |
|---|---|---|
| 颜色识别光线一变就失效 | 开启自动增益 / 自动白平衡 | sensor.set_auto_gain(False);set_auto_whitebal(False) |
| 串口完全收不到数据 | TX/RX 接反、引脚选错、没共地 | 交叉接线,GND 直连,确认 UART1,检查P4/P5 |
| 收到大量乱码 | 没有共地;电平冲突;波特率不一致 | 优先检查共地;统一 115200 |
| 高速运动识别错位扭曲 | 使用卷帘快门镜头 | 换 H7‑R2 全局快门;降低速度 |
| 帧率很低 | 使用高分辨率 | 固定 QVGA,优先使用 ROI 裁剪画面 |
| AprilTag 距离数值完全错误 | 镜头内参 fx/fy/cx/cy 不对 | 重新标定镜头参数 |
| FOMO 运行死机 | 模型过大,内存溢出 | 使用 96×96/160×160 小模型 |
| 识别不到物体 | HSV 阈值不对;曝光不合适;反光 | IDE 阈值编辑器现场调参,硬件加补光遮光外壳 |
| 识别偶尔数据跳变 | 图像噪声 | 滑动平均滤波;调高 pixels_threshold |
| 识别不到目标小车疯狂乱跑 | 没有做识别丢失保护逻辑 | 识别失败直接停止 / 寻优,禁止沿用旧数据 |
重要金科玉律:光照问题优先硬件解决(补光、遮光),不要指望算法搞定光照剧烈变化
六、比赛调试流程(严格按顺序)
- OpenMV‑IDE 运行代码,观察画面、串口输出,确认识别正常
- PC 串口助手模拟报文,调试 STM32 解析逻辑
- 硬件接线,确认共地,静态手持目标测试整套通信
- 低速上电,调试 PID 参数(Kp 从小到大慢慢加大)
- 加入滤波、丢失目标保护
- 全速调试
七、比赛代码保护要点
- 所有识别必须做无目标分支,不能直接使用识别结果
- 禁止大量 print,print 占用串口,干扰自定义通信协议
- 不要在循环内频繁拍照保存图片,容易内存溢出
- 现场不要随意修改镜头,一动镜头内参全部失效
- 阈值建议现场实测,不要直接照搬电脑调试好的阈值