参加电赛最让人头疼的就是技术选型。记得当时看到F题要求时,我和队友面面相觑——要在四天内完成一个能识别数字的智能视觉小车,这简直是把我们往深度学习的大坑里推啊!
最初我们考虑过最"偷懒"的方案:直接用OpenMV的模板匹配。这玩意儿听起来简单,实测下来却是个大坑。我花了整整一个下午调试,发现它只能一帧识别一个数字,模板多了就疯狂掉帧。更致命的是,只要摄像头和数字模板有轻微的角度偏差,识别率就直线下降。这方案在静态测试时还能看,但小车跑起来后画面抖动,效果直接崩盘。
传统算法路线走不通,我们又把目光转向了K210开发板。网上有人说用K210跑YOLOv3效果不错,但实际测试发现两个致命问题:一是官方提供的深度学习框架训练效果不稳定,二是K210的算力实在有限,处理640x480的图像时帧率还不到5fps。这时候已经是比赛第二天凌晨,实验室里此起彼伏的叹气声格外刺耳。
在试遍各种捷径都失败后,我们终于下定决心走最难的路:用树莓派+YOLOv5。这个方案最大的挑战在于数据集——需要手动标注上千张数字图片。凌晨两点的实验室里,三个蓬头垢面的男生围着一台电脑,像流水线工人一样疯狂画标注框。
这里分享个实用技巧:标注时我们用了LabelImg工具,但发现纯手动操作太慢。后来改用快捷键(W调出标注框,D下一张)后效率直接翻倍。更绝的是队友开发的"作弊"方法:先把所有图片按数字分类,再用Python批量生成标注文件,最后手动微调。这样原本需要8小时的工作,我们3小时就搞定了。
数据集准备完毕后,训练过程反而出奇顺利。我们在Colab上开了GPU加速,200个epoch只用了不到2小时。测试时识别准确率高达98%,比之前试过的所有方案都高出一个数量级。那一刻,实验室里爆发出的欢呼声把隔壁组都吓醒了。
模型训练成功只是万里长征第一步,在树莓派上部署YOLOv5才是真正的噩梦。我们用的树莓派4B虽然性能不错,但直接跑原版YOLOv5s还是太吃力。经过反复测试,最终采用这几个优化方案:
python复制# 量化转换命令
python export.py --weights yolov5s.pt --include onnx --dynamic
bash复制# 编译参数关键设置
-D ENABLE_NEON=ON -D ENABLE_VFPV3=ON
python复制import os
os.sched_setaffinity(0, {2,3}) # 绑定到CPU2和CPU3
最坑的是树莓派的USB摄像头驱动问题。默认的V4L2驱动会有3-5帧延迟,我们换了libcamera后终于实现实时传输。这个小技巧后来成了我们组的杀手锏——其他组的小车都因为图像延迟导致控制不稳,只有我们的能精准停在数字前。
比赛最后一天,当基础功能都实现后,我们开始了魔鬼般的参数微调。这里分享几个救命级的调参经验:
运动控制部分:
视觉处理部分:
python复制def auto_exposure(img):
hist = cv2.calcHist([img],[0],None,[256],[0,256])
over_exp = np.sum(hist[200:]) / np.sum(hist)
if over_exp > 0.3:
cap.set(cv2.CAP_PROP_EXPOSURE, -5)
系统集成部分:
比赛最后一晚,实验室变成了不夜城。各组都在做最后的冲刺,而我们的故事才刚刚开始——在最终测试时,小车突然开始跳"机械舞",走两步就抽搐一下。排查过程堪称侦探小说:
解决方案既简单又魔幻:把树莓派的USB线绕个磁环,再在STM32的GND上加个0.1μF电容。这个玄学操作居然真的解决了问题,当时我们都不敢相信。
另一个惊险时刻发生在封箱前2小时。调试时不小心把TF卡烧了,所有代码都在里面。幸好我们坚持了"三备份"原则:GitHub私有仓库、U盘备份、队友电脑各存一份。重新烧录系统只花了20分钟,但心跳加速的感觉持续了一整天。
回看这四天三夜,最大的收获不是奖状,而是解决问题的思维方式。比如当YOLOv5模型在树莓派上跑得太慢时,我们没有蛮干,而是系统性地分析瓶颈:
top命令发现CPU利用率100%vmstat发现大量IO等待这种实战中培养出的debug能力,比任何教科书都管用。另一个深刻体会是:在电赛里,90%的问题都不是技术问题。比如:
这些看似琐碎的"非技术问题",往往才是最致命的。现在想来,电赛就像个微缩版的人生实验室——在这里,我们不仅学会了写代码调电路,更学会了在极限压力下保持冷静,在无数次失败后依然能笑着说出"再试一次"。