(一)绪论

鉴于今年的特殊情况,相较于其他组别,视觉组算是比较幸运的。一是前期改进算法的过程无需依赖任何硬件平台的资源,线上即可完成;二是比赛时间的推迟留给我们大量的时间做前期的准备工作和仿真测试工作。所以今年视觉组的工作进展较为顺利,能够做到随叫随到,随到随调,随调随用。但就从线上答辩的效果来看,今年的准备工作做得还不够到位,接下来我将从以上几点来做详细说明。

(二)自瞄算法思路和成果

较之于去年的代码,今年的算法主要做了一下几点改进:

1.预处理部分

算法的预处理部分参考了2019赛季深大自瞄算法的思路,即膨胀、与运算、膨胀。第一次膨胀针对目标颜色区域,目的是填充亮圈。与运算保证始终提取发光区域。第二次膨胀也是填充非闭合区域。这样经预处理后的二值图可用来做进一步的处理。

 

2.追踪器部分

相较于去年的算法,今年增加了KCF追踪器部分,具体思路是,上一帧识别目标后,将包围目标装甲的最小ROI送入KCF进行初始化,并在下一帧图像的二倍于装甲板大小的ROI中进行追踪,进而得到目标装甲。但在实际运行过程中发现,KCF的初始化和追踪操作耗时较长,在有的情况下不仅不能起到提高运行时间的作用,反而还大大延长了处理时间。所以在之后的算法中,抛弃了之前的KCF追踪器,即得到上一帧目标装甲后,在下一帧图像的二倍于当前当前装甲坐标范围內进行识别。事实证明,相对于追踪器,这种缩小目标区域的方法更有利于提升代码的执行效率。注意在这个过程中的坐标转换关系。

nuscenes视觉 视觉rms_nuscenes视觉

 

追踪效果图

3.子弹下坠补偿

今年代码的子弹下坠补偿直接在平移矩阵中进行,具体思路如下。

nuscenes视觉 视觉rms_预处理_02

 (选自北理珠视觉开源群讨论图)

其中射速由下位机通过串口发送

4.卡尔曼滤波器

第一次有手写卡尔曼滤波器的想法是在DJI攻城狮的逼乎上看到的这篇文章,介绍了卡尔曼滤波器在云台控制中的应用。然后通过这篇文章了解到了手写卡尔曼滤波器的可操作性。

为了从发送端平滑相关参数,也是便于下位机进行预测,参考opencv的官方库自写了卡尔曼滤波器。在将瞬时运动视作匀速运动的条件下,卡尔曼滤波器的状态协方差不必做太多改动。代码中利用卡尔曼滤波器只进行了yaw轴角度的滤波,经过理论仿真来看,滤波器在识别到目标的情况下可以稳定向下位机发送平滑的差值。但由于联调时间太短,故实际效果还需进一步验证。

下图中蓝色为当前实际值,橙色为卡尔曼滤波值,绿色为融合值。

nuscenes视觉 视觉rms_数据集_03

5.solvePNP姿态解算

solvePNP算法进行姿态解算时,通常至少需要目标的三个顶点(这里是四个),为了更加精确的求出相关参数,代码通过单独求每个灯柱的顶点(底边中心点)来作为装甲板的顶点,大大提高了所得距离及pitch,yaw轴角度的精度。(以往总是以包围装甲区域的最小旋转矩形的顶点作为装甲区域的顶点。)测距精度3m内误差<2cm

nuscenes视觉 视觉rms_卡尔曼滤波_04

 

 

(三)算法理论仿真过程

在进行卡尔曼滤波器仿真的时候,采用了log4cplus日志库,其可以方便的将代码运行时的变量值实时的打印在终端或者输出至文件,借助python的matplotlib工具可以将变量值绘制出来,进而可以更加直观的观察出滤波器的效果。唯一的不足是无法实时显示,但具体实现算法也较为简单,也可借助以上方法实现。也可模仿北理珠视觉组采用QT工具自制的上位机  :)

(四)算法存在的不足

即使今年算法在提高精度和运行速度方面做了很多改进,但最终的结果在某些地方还是差强人意。

1.SVM

就速度和训练样本及识别精度而言,SVM是性价比较高的算法之一。但随着机器学习算法的不断改进,有许多简单的神经网络也可甚至更好的完成不同特征的分类任务。并且SVM在实际运行过程中的的确确出现了很多误识别问题,建议以后可根据实际效果更改相应分类算法。

2.自适应阈值

自适应阈值是一个老生长谈的话题,自从去年赛季结束后,许多战队也都提出了这个问题,但具体的解决方法尚未有学校给出。自适应阈值分为两个部分,一是相机的自适应曝光。海康相机的软件曝光可以根据需要实时调节,但官方并没有相应的算法对曝光效果进行评估,故要想完成相机曝光的闭环,需要自己根据识别效果进行考虑。其次是二值化的自适应阈值。二值化后的图像才能作为有效信息进行进一步的处理 ,故挑选合适的阈值进行二值化对识别效果有很大的影响。这里建议参考2019赛季上交开源代码中的大幅预处理部分。

3.先验条件

这里的先验条件是指判定灯柱和装甲范围的最终限制条件,先验条件在代码中多次出现,有些条件冗余重复,亟需更好的方法代替。有些长宽比的限制模棱两可甚至相互矛盾,这都是由于在闭门造车时考虑不周,而在联调是突发奇想产生的结果,希望能找到一个大一统的先验条件,能够考虑到所有的情况而不会出现遗漏。

4.多进程读取海康威视相机问题

在刚开始尝试多进程读取海康威视相机时,出现了只能同时读取一个相机图像的问题,而且在CLION环境中多进程的DEBUG不易操作,所以直到最后也没有发现到底时什么原因。而且子进程和父进程究竟是哪个先运行也不可预知。但要是换成普通USB相机则不会出现这个问题,所以这可能是海康相机内部进程与此出现了冲突,所以不建议直接多进程读取海康相机图像。

最后的解决方案是开辟了两块共享内存,使用两个进程分别同时从两块共享内存中取出图片,再分别进行处理,通过getppid()加以区分,根据不同的PID值通过串口发送不同的帧头,使下位机区分是哪个相机的数据。这样即保证了采集与处理图像的速度,又保证了两个进程互不干扰,互不影响。

(五)就线上评审的几个问题产生的思考

线上评审给视觉组的只有两个问题,也算是一个问题。即Q:怎样提高神经网络的泛化性能?

A:要提高神经网络的泛化性能,主要从以下几个方面考虑:

  • 采用大数据集。特别是RoboMaster比赛中,如果只考虑整车识别,需要建立较大的数据集才能保证识别率(装甲识别除外)。
  • 适当宽范围的超参数搜索。将每个参数的搜索范围扩大,可在一定程度上降低陷入局部最优的概率。
  • 选择合适的dropout rate,使网络不至于过拟合或者欠拟合
  • 批归一化&正则化

除此之外,利用opencv做适当预处理也可以达到事半功倍的效果。

(六)一些建议

  1.  目前重点的工作还是要建立实验室自己的数据集,目前所有的算法还都局限在已有的公开数据集的基础之上。并且各个高校都在逐渐完善自己的数据集(包括作战机器人和雷达站),可见其必要性。在建立数据集的过程中应尽量注意周围光线等环境条件。
  2. 图片像素点的操作尽可能避免加减乘除,可使用opencv的查表操作代替。
  3. 这里提供一个反陀螺思路。可以通过多个装甲板数据得到整车空间状态(旋转周期等),从而控制发弹做到反陀螺。这一过程需注意上下位机时间的同步性。
  4. 百度的AISTUDIO训练数据集比实验室服务器快很多,训练时尽可能首先考虑能不能使用百度的AISTUDIO。使用方法举例。
  5. 视觉算法应该做到自动控制发弹,但优先级不能高于操作手。
  6. 摄像头标定使用Matlab Calibration工具箱比较好,具体做法见这篇教程。
  7. 涉及大量像素迭代操作的运算,能用opencvAPI就尽量避免自己写,opencv的方法一般都会有加速处理。