Giter VIP home page Giter VIP logo

robomaster2021-fosu-awakenlion-opensource's Introduction

佛山科学技术学院醒狮战队2021赛季步兵视觉开源

致谢

首先感谢各高校开源代码为本套代码提供的参考,以及感谢2018、2019、2020赛季算法组师兄们的努力。秉承着开源精神,促进各战队间技术交流提升,我队决定本赛季开源本套代码,希望对其他战队提供一定的参考价值。

说明

  • 本套代码是佛山科学技术学院醒狮战队2021赛季开源代码,仅提供战队间技术交流使用,不得用于任何商业行为。
  • 本套代码主要含有:装甲板识别、大小能量机关击打等。
  • 介于当前开源情况,本套代码着重介绍装甲板识别和大小能量机关击打逻辑等,其他部分不进行具体说明,如对代码有理解上的问题以及bug等,可联系:
    • 包先宏(Ash-1104)
    • 邢邓鸿(GuaiWoLo92)
  • 我们步兵选用的相机分辨率是752 x 480,帧率最高108FPS,镜头是4mm定焦镜头。
  • 在RM2020线上赛中,算法组获得了一等奖,我认为主要是大能量机关的实现是理论成立的,但是非常遗憾,这次对抗赛并没有击打大能量机关,并且在适应性训练没有对大能量机关调试好。

目录

1.主要功能介绍及效果展示

2.依赖环境

3.整体框架

4.实现方案及原理介绍

5.代码规范

6.未来展望

1.主要功能介绍及效果展示

  • 装甲板识别跟踪: 主要分为预处理、灯条检测、装甲板检测、择优、扩展、角度解算这六个部分。预处理部分使用的就算正片叠底+迭代法,灯条检测和装甲板检测基本上都是长宽比等常用的筛选调剂。在非DEBUG_MODE下能够跑满相机帧率(108FPS+),所以就没有再继续加ROI了。

图1-1 装甲板识别跟踪效果展示
  • 小陀螺跟踪击打: 前期的预测都集中在卡尔曼滤波上,由于上车测试时间较迟,后面发现卡尔曼滤波的效果不能达到想象中的效果,调不明白,又因为马上要比赛了,所以退而求其次做了一个强行的“扩展装甲板”,简单来说就是将解算的装甲板向前调整一点,效果还是非常不错,但是没有自适应,但是打击一级的麦轮小陀螺效果还算比较理想,能够有较高的命中率。

图1-2 小陀螺跟踪击打效果展示
  • 能量机关: 能量机关依然使用的是一些特征筛选,装甲板长宽比、父轮廓角点数目、父轮廓外接矩形长宽比等。分为了初始化状态、移动状态、击打状态和等待状态。在调的好的情况下,极限是一块待激活装甲板2.5s内可以尝试3次击打。这里只展示小能量机关,大能量机关实物没能成功做出来,并且在适应性训练的时候没有调好,所以只进行理论上的推演。

    图1-3 能量机关击打效果展示

2.依赖环境

  • 硬件
硬件 型号 参数
运算平台 NUC i5
工业相机 迈德威视MV-UBS31GC 分辨率752 x 480,最高帧率108fps
镜头 \ 4mm定焦
  • 软件
软件类型 型号版本
OS Ubuntu 16.04
IDE Qt Creator-5.8.0
Library OpenCV 3.4.1

3.整体框架

│  main.cpp                            // 主函数
├─AngleSolver                          // 角度解算相关
│      bayesEstimateVelocity.cpp       // 贝叶斯估计源文件
│      bayesEstimateVelocity.h         // 贝叶斯估计头文件
│      GravityCompensateResolve.cpp    // 重力补偿源文件
│      GravityCompensateResolve.h      // 重力补偿头文件
│      PnpSolver.cpp                   // PNP解算源文件
│      PnpSolver.h                     // PNP解算头文件
├─ArmorDetector                        // 装甲板检测相关
│      ArmorDetector.cpp               // 装甲板检测源文件
│      ArmorDetector.h                 // 装甲板检测头文件
│      TargetDetection.cpp             // 目标检测源文件
│      TargetDetection.h               // 目标检测头文件
├─calibration                          // 相机标定参数
├─Camera                               // 工业相机API等
│      CameraApi.h                     // API
│      MVVideoCapture.cpp              // 迈德威视工业相机相关
│      MVVideoCapture.h                // 迈德威视工业相机相关
├─config_file                          // 配置参数
├─debug                                // 编译文件夹
├─Gui                                  // 调试界面相关
│      Gui.cpp                         // 调试界面源文件
│      Gui.h                           // 调试界面头文件
├─Preprocessing                        // 预处理相关
│      Preprocessing.cpp               // 预处理相关源文件
│      Preprocessing.h                 // 预处理相关头文件
├─RuneDetector                         // 能量机关检测相关
│      RuneDetector.cpp                // 能量机关检测源文件
│      RuneDetector.h                  // 能量机关检测头文件
├─save_pic                             // 图像保存路径
├─save_video                           // 视频保存路径
├─Serial                               // 通信相关
│      InfantryInfo.cpp                // 通信相关
│      InfantryInfo.h                  // 通信相关
│      JudgementInfo.h                 // 通信相关
│      PackData.cpp                    // 通信相关
│      PackData.h                      // 通信相关
│      Protocol.cpp                    // 通信相关
│      Protocol.h                      // 通信相关
│      Serial.cpp                      // 通信相关
│      Serial.h                        // 通信相关
├─Settings                             // 主要设置相关
│      Settings.cpp                    // 主要设置源文件
│      Settings.h                      // 主要设置头文件
├─template_path                        // 模板匹配相关

4.实现方案及原理介绍

装甲板识别:

装甲板识别主要识别机器人最明显的灯条部分,而识别灯条则分为预处理和特征提取两大部 分,首先对图像进行预处理,接着对处理后的图像进行特征提取提取灯条,找到符合条件的 灯条后对灯条间拟合装甲板。

1、预处理

预处理部分主要是将图像二值化,而二值化的关键就在于阈值,这里我们采用了正片叠底+ 迭代法,将原图像素 bgr 三通道的权重转化为 0.1、0.2、0.7,接着找出图像最大灰度,最终值:最大灰度 x 0.6+平均灰度 x 0.4,就是二值化的阈值,经过测试,这个方法可以将绝 大多数不发光的物体排除在外,在后面处理轮廓环节能节省较多时间。

2、特征提取

特征提取部分主要是对轮廓进行处理,首先一次筛选,使用传统方法过滤大部分明显不是目标的区域,为后续的分类减小干扰和运算量;然后二次筛选找出敌方颜色的灯柱;最后根据灯柱两两匹配找出所有待定装甲板,并选择最优目标进行辅助瞄准。

1)一次筛选

  • 对所有轮廓长度进行筛选,大于最大阈值或小于最小阈值轮廓排除;
  • 对所有轮廓最小包围矩形长宽比进行筛选,大于最大阈值或小于最小阈值轮廓排除;
  • 对所有轮廓面积进行筛选,大于最大阈值或小于最小阈值轮廓排除;
  • 对轮廓矩形度(轮廓面积与轮廓最小外包矩形面积之比)进行筛选,大于最大阈值或小于最小阈值轮廓排除;
  • 对轮廓似圆度(轮廓面积与轮廓长度之比)进行筛选,大于最大阈值或小于最小 阈值轮廓排除;
  • 多边形逼近,将轮廓拟合多边形,对多边形顶点数量做筛选,小于阈值轮廓排除。

2)二次筛选

  • 对轮廓外包矩形进行角度筛选,偏移角过大则排除;
  • 对轮廓颜色进行筛选,利用轮廓外包矩形四个点的坐标在原图中计算 b 通道和 r 通道的像素差值,筛选出敌方颜色灯柱。

3)装甲板检测

  • 对灯条两两匹配;
  • 对两灯条高度进行筛选,高度差大于最大阈值排除;
  • 对两灯条角度差进行筛选,角度差大于最大阈值排除;
  • 将两灯条在 x 轴上的差值与灯条高度之比进行筛选,比值小于最小阈值或大于最大阈值则排除;
  • 将两灯条在 y 周上的差值与 x 轴上的差值之比进行筛选,比值大于最大阈值则排除;
  • 拟合包含两灯条在内的最小矩形,对矩形面积进行筛选,小于最小阈值则排除;
  • 利用两灯条计算出中间装甲板 4 个顶点位置;
  • 对装甲板矩形宽高比进行筛选;
  • 找到装甲板。

装甲板识别逻辑流程图

图4-1 装甲板识别逻辑流程图

目前仍存在的问题

  • 灯条变形问题,这是这次对抗赛录制的一段视频,可以看到灯条已经成椭圆状了,已经背离了我们的识别逻辑。由于灯条发光,降低相机的曝光时间能够一定程度上缓解这种现象,但是这样也不是特别理想。

图4-2 灯条变形问题
  • 场地灯光误识别问题,这是一直以来都有的问题,是很难避免的,下图为某一场地灯光。其实也能隐隐约约的感觉到,组委会正在努力将大家从传统的OpenCV推向神经网络方向。

图4-3 场地灯光误识别问题

能量机关:

(大能量机关推导中,运用了公式,由于没有插件GitHub无法自动渲染mathJax”,所以这一部分建议下载“大能量机关推导.pdf”查阅,或打开“大能量机关推导.png”查看,或者下载到本地使用软件进行渲染)

  • 目前已改成图片形式,建议在白色背景下阅览

能量机关先导问题:

其实能量机关的主要问题就算在T秒内,能量机关转过的角度。(T:发弹延时+弹丸滞空时间+能量机关亮起时间+云台移动时间等)

小能量机关转速固定为,T秒内转动的角度即为

大能量机关转速按照三角函数呈周期变化。速度目标函数为:,其中 的单位为的单位为

假设速度目标函数为:,其中 的单位为的单位为

进行如下公式推导:

假设初始时间为,末尾时间为,对速度目标函数进行积分,得能量机关总共转过的角度差为:

,得:

即:

即:

化简出,得:

由于官方给定的速度目标函数为:,代入推导公式,得:

因此,仅需知道角度差和时间差,就可以得到,即得到在能量机关转动周期中真正对应的时间,记为(周期),而非程序计时得到的,记为(程序计时器)。(周期)固定不变,在某一时刻,此时计时为(程序计时器),再加上初始程序计时的(程序计时器),得到两者的时间差,通过(周期),就得到当前时刻对应于周期中的时间,记为(周期)。通过(周期)代表(周期),时间间隔为代表,代入公式:

即得到当前时刻起,经过时间间隔T后,大能量机关转动过的角度。

能量机关识别思路:

  • 1 输入图片;

  • 2 预处理:

    • 2.1 根据目标颜色,进行红蓝通道对应相减得到对应的灰度图,如能量机关为红色, 则用红通道减蓝通道,蓝色则相反;
    • 2.2 具体颜色可以从电控通信兵种信息数据获取到敌方颜色信息,比如敌方颜色为红 色,则能量机关颜色为蓝色;
    • 2.3 对灰度图进行阈值分割,得到最终的二值图。
  • 3 特征提取(检查装甲板):

    • 通过识别到的轮廓集,遍历轮廓集,拟合出外包矩形,进行轮廓长度、矩形长宽比、面 积比(轮廓面积 / 外包矩形面积)、轮廓面积等条件的阈值比较,筛选出符合条件(与装甲板相似)的轮廓;
  • 4 找到装甲板轮廓:

    • 4.1 找到 1 个装甲板轮廓,判断有无父轮廓:
      • 有,则判断父轮廓面积是否符合条件,符合再对父轮廓拟合多边 形,计算其角度数,判断角点数是否符合条件(7~10 左右),符合则判断父轮廓 的面积比是否符合条件,符合则存储装甲板(非父轮廓)的旋转矩形;
      • 无,则下一次识别。
    • 4.2 找到多个装甲板轮廓,遍历装甲板轮廓集:
      • 后续与4.1相同。
    • 4.3 其余时候,皆为识别失败。

能量机关识别逻辑流程图如下图所示

图4-4 能量机关识别逻辑流程图

能量机关击打逻辑流程图:

图4-5 能量机关初始化逻辑流程图

图4-6 能量机关状态切换逻辑流程图

5.代码规范

命名风格

风格 例子
文件名 大驼峰 AngleSolver.hpp
类名 大驼峰 class AngleSolver{}
方法 小驼峰 void setTargetSize(double width, double height);
void setCameraParam(const cv::Mat & camera_matrix, const cv::Mat &dist_coeff);
变量 小写+下划线 cv::Mat cam_matrix;
cv::Mat distortion_coeff;
double width_target;
double height_target;
大写+下划线 #define TRUNC_ABS(a) ((a) > 0 ? (a) : 0);

方法常用前缀

方法 说明
initXX() 初始化相关方法,使用init为前缀标识,如初始化布局initView()
isXX() checkXX()方法返回值为boolean型的请使用is或check为前缀标识
getXX() 返回某个值的方法,使用get为前缀标识
processXX() 对数据进行处理的方法,使用process为前缀标识,或使用Proc为后缀标识
saveXX() 与保存数据相关的,使用save为前缀标识
resetXX() 对数据重组的,使用reset前缀标识
clearXX() 清除数据相关的
removeXXX() 清除数据相关的
writeXX() 写入文件相关
readXX() 读入文件相关

注释规范

场景 规范
代码块 统一规范:
//-----------------------------------【标题】----------------
// 描述:
//-----------------------------------------------------------------
方法 统一规范
/**
* @brief 这里书写该方法的简介,包括其作用等
* @param 第一个参数说明
* @param第二个参数说明
* @return 返回值说明
* @author 参与开发人员
* @date 2021.8.4
*/
宏定义 例: #define SHOW_IMAGE //如果注释掉则不显示图片,有利于加快运行速度
成员变量 如果变量名不能很好的显示其含义或有特殊用途,就需要注释
其他 不容易理解的逻辑部分

常用代码书写规范

  • ”,“之后要留空格,for语句中”;“后需要留空格;
  • 赋值操作符、比较操作符、算数操作符、逻辑操作符等二元操作符的前后应留空格;
  • 一元操作符前后不加空格;
  • 大括号换行,如果if、for等后只跟有一行的可不加大括号
  • 其他书写规范尽量与Visual Studio中默认书写规范一致。

6.未来展望

  • 继续研究反小陀螺算法,提高反小陀螺算法的自适应程度,自动化程度,提高反小陀螺算法击打命中率;
  • 将整体算法从传统算法向神经网络转移;
  • 对移动目标,继续研究或发现新的解决方案,提高击打移动目标的命中率;
  • 在装甲板识别中加入数字识别,降低误识别概率。

robomaster2021-fosu-awakenlion-opensource's People

Contributors

ash1104 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.