讲解RM视觉部分(一) 英雄 步兵 哨兵的通用OpenCV(Open Computer Vision 开源计算机视觉)部分

学弟们在看该部分代码之前,应该 ①熟悉《OpenCV3编程入门》(毛星云版)的前8章,(熟悉:要么你能背诵, 要么可以在5秒之内在找到你想要的函数);
②知道计算机视觉所涉及到的几大坐标系(世界坐标系,相机坐标系,图像平面坐标系....) https://blog.csdn.net/weizhangyjs/article/details/81020177 (能看懂即可,我的代码里涉及到坐标系变换,PnP里也涉及到坐标系变换)
③除上述,你还必须掌握的OpenCV:PnP, kalman滤波
④当然,C++还是得会,C++多线程要会 ⑤会看别的学校的代码,可以在github上找到

1.调试工具

由于经常需要调试程序,输出一些变量啊,看一些变量的变化情况啊,所以把常用的那几个封装在一起

Debug

反正没人喜欢看字,就看图吧,当然还有一些宏定义方便调用

loading picture
loading picture

JLink

loading picture

主要用来显示一些变量的变化情况,一般用于调kalman滤波的参数,我搞的太花里胡哨了,所以调用的时候会极大降低识别速度,慎用

2.步入正题

loading picture

↑ 以上为原图, 减小光圈,降低曝光有利识别, 降低曝光至刚好可以看清数字

2.1识别灯条

开始RM视觉的编写后,你会发现你永远离不开灯条识别、灯条匹配,以下都是我们的方法,仅供参考,你们可以写出更好的
灯条识别的基本步骤: 二值化->边缘检测->最小包围图形->筛选

(一)二值化:找出图片中敌方的颜色
你们一定会听到"一定要优化灯条匹配的条件,节约时间,因为那里有两层for"这类的话. 两层for的时间复杂度为O(n^2),比较耗时, 其实还有一个地方有两层for---二值化
二值化,你必须遍历每一个像素点,如果把图像看成二维数组,将用两重for遍历, 在640*480的图像中这一步的耗时将多于灯条匹配. 所以我直接遍历所有像素,筛选出目标颜色(函数Contours TargetFind::getContours)
相比于有些学校使用的"先转灰度图,在阈值化(找到亮的区域),再选出想要的颜色"这种方法要快2ms左右
同时,使用

loading picture
loading picture

当然,还有更好的方法可以提高识别速率


(二)边缘检测:找到灯条的轮廓方便后续匹配
边缘检测基本就是调用书里的函数,在这里不多讲,你至少要知道每个参数的意义


(三)最小包围图形
为啥这里说的是最小包围图形, 因为我尝试过最小包围矩形,和椭圆拟合(cv::fitEllipse椭圆拟合), 椭圆效果略好一点点(不是很明显),当然建议你们都尝试一下,可能是我参数没调好.
这里一定要注意!!!!!!!!!一定要了解opencv中旋转矩形的表示方法,因为你会发现:有时两个相互平行的旋转矩形,角度相差90度.


(四)识别条件
识别灯条的条件一般为:长宽,面积,角度; 相关阈值还是要自己调

2.2灯条匹配(装甲板识别)

两重for循环遍历灯条的两两组合, 找到符合条件的组合(装甲)

这里列举以下, 我用到的条件:
①灯条大小接近;
②角度接近
③错配度(函数 malposition)较小(这里我参考了上海交大的代码)
④面积和距离满足比值条件
这些条件可以识别交近距离内(3m之内),大部分装甲板

以下是子午用的方法:
三维的装甲板四个特征点通过坐标变换可以得到图像中的特征点. 子午通过计算变换矩阵,判断是否为装甲板

loading picture

以上是装甲识别部分, 具体的实现还是要看代码, 还是要自己动手写

PS:图像的显示在调试的时候很有用,但在比赛的时候一点用也没有,建议使用单独的线程进行显示,不影响识别速率,不影响预测的△t

3.代码

https://github.com/shilei31415/AutoShot