比赛那天下午太阳斜着打在赛道右侧目标板上的数字在画面里白成一片。我们调试了三个星期的分割算法在那条直道上一瞬间全部失效车子直接冲出了赛道。事后复盘问题根本不在算法而在曝光时间——相机自动曝光被太阳骗了目标板上的边框和字符全部过曝HSV阈值设得再准也救不回来。这个教训让我意识到目标板识别从来不是一个纯粹的OpenCV算法问题而是一条从镜头到决策的完整链路每一环都必须可控。“走马观碑”这个队名取自那个能一边策马疾驰一边看清碑文的典故。放在智能车竞赛里其实就是我们对视觉系统的期望车跑过去的同时把路边目标板上的内容又快又准地读出来。然而现实往往很打脸跑起来之后算法能不能稳住完全看天吃饭。这篇文章把我们组在目标板识别这条链路上踩过的坑、验证过有效的方法以及一些可以直接拿来用的思路整理出来。内容围绕OpenCV但又不只是OpenCV——相机参数、图像预处理、轮廓筛选、透视矫正、内容识别、嵌入式提速、现场排障都会讲到。如果你也在准备类似的竞赛或者正在折腾基于OpenCV的目标检测项目这篇文章应该能让你少走不少弯路。1. 竞赛里目标板识别的真正难点不是“认不出”而是“不信任”1.1 目标板在竞赛中的作用与“走马观碑”的含义智能车竞赛里的目标板一般是放置在赛道旁边的平面牌子上面有数字、字母或者特定符号。车子识别到之后要执行对应的控制动作比如减速、停车、换道、切换赛道模式。它的逻辑本身不复杂但难就难在车子是在高速运动状态下用一颗低成本摄像头去捕捉一张可能倾斜、可能反光、可能被阴影遮挡的牌子还要在几十毫秒内给出一个可靠结果。“走马观碑”这个典故说的是古人骑马经过碑林马在跑人却能把碑文看完记下。我们组取名的时候就是看中这个“快而准”的感觉。但真正跑起来才发现视觉系统离这个境界差得很远。目标板在画面里往往只停留几百毫秒如果算法不能在第一时间锁定它等车子贴到近前再识别就已经来不及了。所以这个题目的本质不是“能不能识别”而是“在什么速度和什么环境条件下识别结果还可信”。1.2 “快、稳、省”三个字如何贯穿所有算法选择整个调优过程中我脑子里始终绷着三个字快、稳、省。快是指单帧处理时间必须控制在竞赛主控可接受的范围内。我们当时的平台是一块入门级嵌入式开发板OpenCV跑在CPU上全图640×480分辨率做一遍完整处理如果设计不合理耗时能飙到80毫秒以上直接拖垮控制频率。稳是指在不同光照、不同角度、不同距离下识别结果不能忽好忽坏。赛场的阳光、阴影、反光是我们控制不了的算法必须对这些变化有足够的容忍度。我后来定了一条规矩任何识别结果必须带上置信度连续两帧以上一致才允许触发控制动作。省是指资源和时间的节省。嵌入式平台的内存和算力都有限能不做高分辨率处理就不做能用单通道绝不用三通道能在小范围ROI里搜索就绝不全图扫描。省下来的算力可以用来提高帧率帧率上去了运动模糊和漏检问题也会相应缓解。这三个字听起来像口号但后面每一个具体方案的选择其实都是拿这三个字去衡量之后的结果。2. 从相机采图就要开始较真曝光、帧率与图像质量2.1 OpenCV读相机的工作原理与帧缓冲很多队伍拿到相机第一件事就是cv2.VideoCapture(0)然后直接进入图像处理循环很少去想这一行代码背后发生了什么。实际上OpenCV的VideoCapture在Linux平台上默认通过V4L2协议读取设备。相机把光信号转换成数字信号之后数据先进入内核的驱动缓冲区再由OpenCV把它拷贝到用户空间最后封装成Mat对象供我们使用。这里有一个非常容易踩的坑缓冲区是有队列的。如果你的处理速度跟不上采集速度帧会在缓冲区里不断堆积你读到的那一帧并不是“最新”的画面而是几百毫秒前的旧帧。对目标板识别这种对实时性要求极高的场景这是致命的。解决办法是主动清空缓冲区或者在每次读取前设置较短的缓存模式保证拿到的永远是最新的帧。另外很多人在调试时会写一个带窗口显示的循环然后发现画面卡住不动半天才反应过来是cv2.waitKey(0)的问题——参数写成0表示无限等待键盘输入没有按键就卡死在那。竞赛代码里千万别用waitKey(0)要用waitKey(1)并利用返回值做按键响应否则调试五分钟找卡死原因三小时。2.2 相机选型与竞赛场景的参数建议目标板识别对相机的要求其实和拍短视频完全不同。我们需要的是低延迟、固定曝光、尽量少的运动模糊而不是高分辨率和高色彩还原。我们当时对比过几款相机最终留下来的配置思路可以用下面这个表格概括参数维度USB UVC相机CSI接口相机我的建议开发难度低即插即用中等需要配置驱动预算有限选UVC图像延迟相对较高较低追求极限选CSI分辨率可到1080P可到720P/1080P竞赛建议720P以下快门类型多为卷帘快门部分支持全局快门动态场景全局快门更稳固定参数控制部分支持较完善选支持手动曝光的型号分辨率方面我不建议为了“看得清”而盲目上1080P。目标板在画面里占的像素面积通常不大确实需要一定分辨率才能看清内容但720P其实已经足够。分辨率翻倍处理时间不是翻倍而是三到四倍地涨因为后续轮廓查找、形态学的耗时都跟着像素数量走。更合理的做法是用640×480采集在目标板出现时对局部区域做裁剪放大这样既保证了细节又控制住了整体计算量。2.3 固定曝光与白平衡让画面成为一个稳定输入这是我在那个“过曝翻车事故”之后学到的第一课。竞赛场地在室内外都有光线变化非常剧烈。相机的自动曝光和自动白平衡在静止场景下效果还行但车一跑起来镜头看到的画面连续变化自动参数就会一直来回调整画面的亮度、色偏每帧都在飘。识别算法面对这种无规律的输入变化再稳定也会崩。我们的做法是把相机完全设置成手动模式固定曝光时间、固定增益、固定白平衡。在赛道起点处对准光线最复杂的区域采集一帧画面反复调整这几个参数直到目标板的颜色和对比度在画面里最清晰然后把这一组参数写死。这样做的代价是如果你跑到一个光线突然变暗的区域画面会偏黑但只要目标板的颜色特征还能从背景中分出来颜色分割依然有效。相比之下自动曝光带来的“每帧亮度不同”才是颜色分割算法最怕的事情。关于曝光时间这里可以给一个估算公式。假设车速是3m/s目标板宽度是0.3m目标板在图像中水平方向占500像素。如果曝光时间是1ms车子在曝光期间前进了3毫米换算到图像里大约是5个像素的拖影。5个像素的模糊对字符识别来说还在可接受范围但如果你用的是自动曝光在暗处曝光时间可能被拉到10ms以上拖影就会变成几十个像素整个字符糊成一团任何算法都救不回来。所以曝光时间宁短勿长哪怕画面稍微暗一点也要保证没有明显的运动模糊。2.4 畸变与标定什么时候该做什么时候可以不做目标板识别需要做相机畸变校正吗我的答案是分情况。如果你用的是鱼眼镜头或者广角镜头画面边缘的目标板会明显变形矩形边框变成弧线这时候透视矫正会出错必须做标定。但大多数竞赛场景用的是普通视场角镜头畸变集中在画面边缘而目标板出现的位置往往在画面中前部——只需要算准这个区域畸变的影响可以忽略。我们组当时没有做完整的棋盘格标定而是采取了一个更接地气的策略让目标板尽可能落在图像中心附近同时把识别算法里的几何校验条件放宽一些。比如矩形判断时允许边缘曲率有很小的波动面积和宽高比的容差也适当加大。这样做省去了标定环节的时间在实际赛场上完全够用。如果你后续打算做更高精度的定位再去补标定也不迟它能帮你把角点坐标误差从几个像素降到亚像素级但对字符识别来说这个精度提升的收益并没有想象中那么大。3. 预处理链路的重构我为什么放弃Canny而改用HSV分割3.1 灰度图Canny的经典组合在赛道场景里的尴尬很多OpenCV教程里检测一个目标的标准流程是转灰度、高斯模糊、Canny边缘检测、轮廓查找。这个流程在实验室环境下很漂亮但拿到赛道上就有点水土不服。Canny的核心是找灰度梯度变化剧烈的点可赛道场景里梯度大的地方太多了轮胎痕、阴影边界、赛道边缘、反光高光全都会产生边缘。你辛辛苦苦找出来一堆边缘再从中筛出目标板的轮廓等于先把所有候选者都拉进来再一个个排除误检率自然居高不下。更要命的是Canny的两个阈值low_threshold和high_threshold对光照变化非常敏感。阳光强的时候目标板字符和边框的梯度变大阴天的时候梯度变小。同一组阈值上午好用下午就失灵每个参数都要重新调。这种不稳定性在竞赛场景里是不可接受的因为我们在赛场上没有充足时间逐帧调参。所以我的建议是除非目标板本身是纯灰度、没有颜色信息否则不要一上来就走Canny路线。把颜色当作第一道筛选条件效果会好很多。3.2 HSV颜色空间分割让“颜色”成为第一道筛选目标板的设计通常是有讲究的要么是深色边框配浅色底要么是特定颜色的矩形框中间放字符。这些颜色信息在BGR空间里很难直接用阈值表达因为BGR三个通道对光照变化都很敏感。转换到HSV空间之后H色相通道把颜色本身和亮度剥离开只要色相范围选对了画面整体变亮变暗基本不影响分割结果。用OpenCV实现很简单核心就是cv2.inRange。我当时是自己写了一个带滑动条的小工具把H、S、V的最小值和最大值做成六个滑条对着实际赛道画面一边拖动一边观察二值图效果找到最合适的区间。有一点要特别注意OpenCV里H通道范围是0到179S和V范围是0到255。很多从别的资料里抄来的HSV范围值没换算直接用结果啥也分割不出来。如果你的目标板用的不是纯色而是多种颜色混合我建议优先选视觉面积最大、颜色最稳定的那个颜色作为分割对象。比如白底黑字的板子你就别试图分割白色因为在强烈阳光下白色会直接曝成一片阈值全域塌陷。更好的选择是分割深色边框或者把字符颜色抠出来这样即使过曝颜色特征也还在。3.3 滤波与形态学在二值图上做减法HSV分割之后得到的基本是一张二值图里面除了目标板区域还会有很多零散的噪点。处理噪点时很多人的第一反应是加大高斯模糊。但要注意高斯模糊是针对灰度图的对于二值图更合适的操作是形态学。我们的标准处理顺序是先做一次闭运算用cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)把目标板内部因为反光或阴影产生的断裂缝隙连接起来再做一次开运算把背景里的小噪点去掉。核的大小很关键我推荐从3×3开始试不要一上来就5×5甚至更大。核越大区域边缘被腐蚀和膨胀得越厉害最后轮廓定位的像素级精度就越差透视矫正时角点偏移就越明显。这个阶段还有一个容易被忽略的点不要在每帧里重新创建核和形态学的临时Mat。嵌入式平台上内存分配是有开销的反复创建销毁会拖慢速度。把核和临时变量定义在循环外面一帧结束后复用。3.4 动态ROI把全图搜索变成局部跟踪预处理做得再好全图扫描始终是性能瓶颈。目标板在车前方的出现位置通常是有规律可循的——赛道是连续的目标板不会瞬移。所以我们的策略是上一帧找到目标板之后记录它的中心坐标下一帧只在以这个坐标为中心、向外扩展一个固定边长的矩形区域里做分割和轮廓查找。车速越快扩展区域就要越大车速慢或者直道可以把这个区域压得很小计算量能降到原来的五分之一。这个思路其实就是一个非常轻量的跟踪器。它和光流、KCF那些跟踪算法的区别是它不预测目标板的运动模型只是单纯缩小搜索范围。好处是几乎零成本坏处是一旦连续几帧没找到目标板ROI就会漂移。处理办法也很简单如果连续丢失超过两帧就把ROI重置为全图重新搜索一次。等目标板重新被锁定再切回局部模式。4. 目标板定位与内容识别的主流程设计4.1 轮廓筛选的“漏斗”从面积到几何形状拿到二值图之后下一步是cv2.findContours。这里建议使用cv2.RETR_EXTERNAL只检测外轮廓和cv2.CHAIN_APPROX_SIMPLE压缩轮廓点。前者可以避免同一个目标板被内部字符轮廓分割成多个候选后者可以减少后续计算的顶点数量。轮廓筛选要设计成一个多级漏斗每级过滤一批干扰项。第一级是面积过滤面积太小的轮廓直接丢掉。但这里不能固定一个绝对像素值因为目标板离车远的时候在画面里的面积很小近的时候又很大。我习惯用相对值比如“面积小于当前ROI区域面积百分之二的轮廓直接忽略”。第二级是宽高比过滤目标板通常是个矩形宽高比固定在一个范围里比如0.5到2.0之间明显偏离这个区间的直接排除。第三级是矩形度过滤也就是计算轮廓面积占其最小外接矩形面积的比例。一个规整的矩形目标板这个比例应该在0.7以上而树叶、轮胎印、阴影碎片这些不规则形状比例会低很多。经过这三层筛选之后候选轮廓通常就剩下一两个了后面再做内容识别就轻松很多。4.2 最小外接矩形与透视矫正把斜着的板子掰正找到目标板轮廓之后用cv2.minAreaRect求最小外接矩形得到一个旋转矩形里面包含了中心点、宽高和旋转角度。通过这四个角点和目标板在标准正视图中的四个角点做对应就能用cv2.getPerspectiveTransform算出透视变换矩阵再用cv2.warpPerspective把目标板区域矫正成一个正面视角的图像。透视矫正在目标板识别里非常关键。车子跑到目标板侧面的时候板子在画面里是一个梯形甚至更畸变的四边形这会让后续的字符模板匹配非常吃力。矫正之后不管车子是从什么角度经过我们都能拿到一张近似正面的、固定尺寸的板内图像模板匹配或者字符分割的难度大幅下降。这里我还想提一个更轻量的“卡尺工具”思路。目标板边框通常是一条比较直的边缘如果在矫正之前就能确定边缘位置完全可以在ROI内沿法线方向做边缘投影找到边缘在哪一行哪一列不需要跑完整轮廓查找。这种卡尺法在OpenCV里没有现成函数但实现起来很简单在目标区域内按行扫描灰度突变点做一个累加投影峰值位置就是边缘所在。它的速度比轮廓法快抗光照干扰能力也更强。不过它适合边缘清晰的场景如果目标板边缘颜色和背景接近还是得用轮廓法兜底。4.3 板内内容识别模板匹配与特征判断的取舍矫正完成之后板内内容识别就有两条路可选。第一条是模板匹配cv2.matchTemplate用cv2.TM_CCOEFF_NORMED归一化相关系数作为相似度。这个方法在字符种类固定、字体固定的竞赛场景里非常实用。我们当时的做法是拍好0到9十个模板目标板区域矫正后分别和这十个模板做匹配得分最高的那个就是识别结果。注意模板大小和目标区域大小要尽量一致或者匹配前把目标区域缩放到模板的尺寸否则相关系数会受到尺度差异的影响。第二条是基于轮廓的字符特征识别。把矫正后的图像二值化找字符轮廓然后提取每个字符的面积、宽高比、笔画密度、孔洞数量这些特征喂给一个非常小型的分类型器。这个方案的优点是泛化能力比模板匹配强字体变化也能识别缺点是开发量和调参成本高很多需要准备样本数据。竞赛场景下我建议先用模板匹配跑通链路如果确实遇到字体不固定或者倾斜严重的问题再考虑加特征分类。这两种方案不是互斥的也可以结合先用颜色分割判断板子边框颜色再用模板匹配确认具体字符两个结果交叉验证整体置信度会更高。4.4 置信度与帧间一致性让结果更可信很多队伍在识别成功后就直接输出结果这是很危险的。模板匹配的得分即使很高也可能因为光照变化而产生一次性的误判轮廓特征的组合也可能意外命中背景里某个相似形状。我坚持要给每个识别结果附加置信度再设置多级处理策略。具体来说如果匹配得分超过0.85直接接受如果在0.70到0.85之间暂时不动作等下一帧结果来确认如果最近三帧中有至少两帧识别出同一个字符且置信度都超过0.70就认为这个结果是可信的输出给控制模块。连续三帧都不满足条件就丢弃这个目标板让车子按默认策略行驶。这个“多帧确认”的机制本质上是在用时间换可靠性对低速和中高速场景都有效。还要强调一点识别结果必须带时间戳。车子的控制模块在拿到结果时需要知道这个结果是什么时候看到的因为车在跑一帧的时间就能前进好几厘米。没有时间戳控制模块就无法准确计算目标板的位置触发时机就会偏差。5. 嵌入式平台上的OpenCV提速与部署优化5.1 算法侧的提速手段分辨率、灰度、缓存复用嵌入式平台上做OpenCV第一步永远是降低分辨率。640×480采集预处理阶段可以先缩放到320×240。目标板识别这种任务320×240下的颜色分割和轮廓定位大部分时候都够用。只有当车已经离目标板很近、需要看清具体字符的时候才在ROI区域内裁剪原始分辨率的局部图像放大后再做模板匹配。这样既保证了远处快速发现目标板又保证了近处的识别精度。第二个提速手段是全程使用单通道。颜色分割用HSV的话H通道和S通道可以单独提取不需要同时处理三个通道。模板匹配本身也支持灰度图。字符识别阶段完全可以用单通道图像完成。三通道转单通道cv2.cvtColor会消耗不少CPU时间但要记住这个转换不是必须每次都做很多操作可以在同一个通道上完成后再统一转换。第三个提速手段是缓存复用。OpenCV里很多函数会输出新的Mat如果不加控制一秒钟跑30帧就会产生几百次内存分配。识别循环里要尽量用cv2.Mat的复用特性把一些中间的Mat对象声明在循环体外利用.setTo(0)或者直接把结果写到同一个Mat上避免new和delete的反复调用。这个优化看着不起眼在嵌入式平台上却能让帧率提升10%到20%。5.2 工程侧的线程与内存优化纯算法优化是有上限的想要榨干嵌入式平台的性能还得在工程架构上下功夫。我强烈建议把图像采集和图像识别分成两个线程采集线程只负责VideoCapture.read()把帧放进一个队列识别线程从队列里取帧做处理。这样即使识别偶尔变慢采集线程也不会丢帧处理完之后队列里始终有最新的数据不会出现“读到旧帧”的延迟问题。线程之间传递帧的时候尽量不要直接传Mat对象因为Mat是浅拷贝底层数据会共享。更安全的做法是用一个固定长度的环形缓冲区里面预先分配好N个Mat采集线程和识别线程交替使用通过索引来避免拷贝。如果平台内存足够直接传一份浅拷贝再做深拷贝也可以但要确认不会出现数据竞争。嵌入式Linux下面还可以调整CPU的调度策略和频率。比如把识别线程绑到某个CPU核心上设置实时优先级可以减少调度延迟。另外如果OpenCV是编译安装的可以在CMake配置里只保留用到的模块比如imgproc、imgcodecs、videoio、calib3d去掉那些用不到的视频分析、高GUI等功能库的体积和内存占用能小很多。启动速度也会有明显改善。5.3 离线回放与参数整定OpenCV调参不要在现场进行这是我最想强调的一条经验所有参数调整都应该在离线回放阶段完成而不是到了赛场再改代码。赛场上几分钟的调试时间根本不够你判断一组参数在多种光照下是好是坏。具体操作是比赛前用真实赛道录制多段原始视频每段覆盖一种典型场景顺光、逆光、阴影、傍晚。录制时不要用视频压缩或者用低压缩率编码避免压缩噪声影响分割质量。然后在电脑上把这套识别代码跑在录制视频上输出每一帧的识别结果、耗时、目标板中心坐标保存成日志。再写一个离线评估脚本统计正确识别率、误检率、漏检率和平均处理耗时。参数整定可以做得更科学一点。HSV范围、形态学核大小、面积过滤比例这些参数组合起来是一个高维搜索空间。手动调参效率很低可以用网格搜索或者粒子群优化算法在离线环境中自动搜索一组最优参数。粒子群在我看来很适合这个场景参数维度不多目标函数可以直接定义成“识别正确率减去误检惩罚”迭代几十轮就能收敛到一组稳定参数。这比人工在现场抱着一台电脑试半天要靠谱得多。找到最优参数后写进配置文件比赛时主程序启动时读取现场只需要加载不再改代码。6. 赛场实测中遇到的疑难杂症与排查记录6.1 高亮过曝与反光白成一片怎么救回到开头那个场景太阳斜射导致目标板过曝整个板面白成一片。这种问题靠调HSV阈值是解决不了的因为过曝区域所有颜色都被压缩到白色附近H通道已经失去意义。我的处理优先级是这样的第一步降低曝光时间让画面整体暗下来目标板的颜色特征重新出现。第二步如果降低曝光导致暗部细节丢失就加一块偏振片滤掉地面的反射眩光。第三步改分割策略不分割白底而是分割深色边框或字符因为深色区域在过曝时不会立刻饱和还能保留下轮廓信息。如果这三步都来不及还有一个临场应急的手段在预处理阶段先把高亮区域的亮度值做一个非线性压缩比如对V通道做一次幂次变换把接近255的高光区域压回200以内让过曝区域重新出现一点点层次感。这个方案对字符边缘的恢复有帮助但对整体识别率的提升有限只能算是救急。6.2 运动模糊与拖影的应对运动模糊是速度上来之后一定会遇到的问题。最直接的解决办法是缩短曝光时间但曝光时间太短画面会变暗颜色分割的信噪比又不够。这组矛盾需要根据赛道光线条件在赛前提前测试找到一组“拖影不明显”和“颜色可分”的平衡点。另一个容易被忽视的因素是卷帘快门。卷帘快门在拍摄快速运动的物体时会产生竖直方向的空间畸变目标板在画面里可能变成斜的或弯曲的。这个畸变不是透视导致的而是传感器逐行曝光的时间差造成的透视矫正也无法完全修正。如果条件允许尽量选择全局快门的相机如果只能用卷帘快门那么识别时对轮廓宽高比和矩形度的容差要适当放宽不要因为目标板被拉长了一点就把它丢掉。处理完硬件层面再在算法层面对症下药。可以在预处理阶段添加一个轻量的锐化卷积核让模糊的字符边缘重新变清晰。但锐化不能做太狠过度锐化会产生强烈的振铃效应导致轮廓周围出现假边缘反而干扰矩形度判断。我用的是类似于[[0, -1, 0], [-1, 5, -1], [0, -1, 0]]的核跑起来基本没有额外开销。6.3 误检与漏检的平衡艺术目标板识别的过程中误检和漏检是此消彼长的关系。阈值放得宽漏检少但误检多阈值收紧误检少但漏检增加。在我个人的实践中漏检比误检更容易处理因为控制逻辑可以允许“这一帧没看见目标板”这样车最多晚一点做出反应大概率还在安全范围但误检的代价很高如果车把背景里一块相似颜色的牌子当成了目标板可能提前急停或者错误换道整场比赛就毁了。因此阈值设置要偏保守宁可偶尔漏检也不要误检。结合前面说的多帧确认机制这个策略在实际运行中非常稳定。还有一个技巧不同赛道区域可以加载不同灵敏度配置。比如在高速直道上识别阈值放宽一些好让车更早地看到目标板在急弯附近把阈值收紧避免因为路面标志干扰产生误检。这些配置通过一个简单的状态机来切换就行代码上不复杂但效果立竿见影。6.4 调试现场的小习惯最后分享几个让我省了大量现场时间的调试习惯。第一日志必须带时间戳。每一帧识别结果、置信度、耗时、目标板坐标都要写进日志文件用chrono或std::chrono标好时间点。赛后翻日志定位问题比在现场盯着屏幕猜要高效太多。第二保存关键帧截图。触发动作的那一帧和连续丢失目标板的几帧自动保存原始图和预处理后的二值图。这样即使赛后在棚里也能根据保存的图片还原当时的场景找到算法失效的准确原因。第三在调试画面里实时叠加识别结果把目标板轮廓、中心点、字符识别结果、置信度直接画在帧上用窗口显示出来。这个画面不仅方便自己调试也方便队友快速理解当前视觉状态排查问题时能少很多沟通成本。这些习惯看似琐碎但碰到疑难杂症时它们是让你从“一头雾水”到“定位根因”最快的一条路。目标板识别做到最后拼的不是什么高深算法而是对图像链路每一环节的掌控。把曝光固定住把预处理想清楚把轮廓筛选设计成漏斗把置信度机制加上这套组合拳在竞赛里已经足够稳定。如果你也在备赛我的建议是赛前一周就不要大改算法了只调参数、跑回放、稳定心态。等上了赛道车子真的能像“走马观碑”一样刷地一下跑过去目标板上的内容一次就读出来那种感觉确实比拿奖还爽。