某款篮球机器人的视觉组成部分—简单分享


篮球机器人是一个综合运动控制,感知,决策的综合系统。而机器人的视觉系统则是其中重要的一环,承担了识别与定位目标球,并返回位置和距离信息给决策部分的重要任务。本文以篮球机器人为例,研究机器人的视觉系统原理。首先,介绍了篮球机器人系统结构层次及篮球机器人比赛规则,明确篮球机器人视觉部分主要任务要求是对目标进行识别与定位。然后对篮球机器人从软件和硬件的组成做必要的介绍,并对视觉部分的代码运行原理做深入浅出的详细分析。最后给出了实际的调试效果,并简要的说明了篮球机器人视觉部分还存在的问题,这也是我们下一步要着力解决的方向。


篮球机器人,视觉原理,Kinect,OpenCV,定位,识别


篮球机器人是一个属于人工智能和机器人学科领域的应用型研究课题,它综合了人工智能、 机器视觉、机械结构和智能控制等多方面的技术,具有很大的研究意义。篮球机器人比赛是中国机器人大赛中的一个重要比赛项目,其要求参赛机器人具有独立的行为决策、运动控制与视觉感知等能力。

机器人的视觉系统则是其中重要的一环,承担了识别与定位目标球,并返回x轴相对位置信息和距离信息给控制决策部分的重要任务。要理解篮球机器人的视觉原理,首先要熟悉视觉与其他部分,包括运动,硬件,控制的联系,并且要对篮球机器人的比赛规则有清楚地认识,并要对视觉系统的硬件组成,软件工作原理有着透彻的理解。本文即围绕着这些方面进行展开,实现对篮球机器人视觉系统的研究。

篮球机器人视觉系统


篮球机器人一般由感知子系统、决策子系统、运动控制子系统、通信子系统和投球控制子系统构成。各子系统之间的关系

各子系统的功能如下:

感知子系统:采集各传感器的数据,并通过通信子系统传递给决策子系统。感知子系统常采用的传感器主要有 Kinect 传感器、激光传感器、里程计和陀螺仪等。

决策子系统:接收并处理从通信子系统传来的信息数据,将其转化为决策指令。完成这部分功能的称为上位机,一般采用笔记本或者工业计算机。

通信子系统:完成上位机和下位机以及控制器和传感器之间的数据传递。

运动控制子系统:将决策子系统发送的决策指令转化为机器人的运动控制信息,并使其完成指定动作。

投球控制子系统:将决策子系统发送的决策指令转换为控制弹射机构的电平信号,完成拾球投球等动作。

2.2篮球机器人比赛规则

从 2012 年开始,中国机器人大赛增加了篮球机器人比赛项目。比赛的标准场地如图3所示,场地与人类篮球比赛场地一模一样,就是标准的篮球场,场地中所有分界线均为白线。比赛用球为标准的篮球和排球,颜色在比赛前由官方指定,比赛用的机器人其尺寸不能超过 65cm×65cm×90cm。 

赛时,由于受目前机器人技术的限制,机器人与机器人之间要跟人类一样传递篮球很难实现,所以比赛规则规定,每场比赛同时四个高校的机器人上场比赛,每个高校只允许一台机器人上场,机器人必须避开场上的静态障碍物和动态障碍物(其它高校的机器人),移动到场上放置球的位置,按照指定的取球顺序取球,然后运动到三分线内投球,己方四分之一半场的球全部投篮完毕后,可以去寻找另外四分之三场地的球,最后准确投进球多的队伍获胜,如果两个队伍投入球的数量一致,则用时短的队伍获胜。

硬件上,篮球机器人采用了Kinect1(如图5所示),它是一种高性价比的视觉传感器,它可以同时捕捉彩色图像和深度信息。Kinect 除了有一般的 RGB 摄像头外,还配有一个 3D 景深摄像头和红外摄像头。其两侧还有 4 元线性麦克阵列,下方有一个可编程仰角控制马达。RGB 摄像头可以获取视野范围内的彩色图像。红外摄像头可以获得可视范围内的物体深度图像。


软件上,视觉系统以OpenCV,一种开源的视觉编程库为主要工具,进行深度图和彩色图的处理,从而实现定位和目标识别的效果。编译工具是微软公司的Microsoft Visual Studio13软件。接下来的篇章中,我将着重研究视觉系统的软件部分工作原理。


视觉系统代码工作原理

进入主函数,首先是初始化串口,串口号是从设备管理器来看。串口通信实现上位机和硬件的直接沟通,一方面可以发送目标球的号码,命令视觉部分识别特定的目标球,另一方面,得到的定位信息也要通过串口发送给机器人的控制系统。

然后,初始化OpenNI,设置图像的生成格式和帧频。OpenNI是开源的Kinect驱动中间件,我们使用它来实现驱动kinect进行工作,进而生成原始的色彩图和深度图。

进入主循环,首先不断地接受串口的指令,确定目标球,利用OpenNI生成并转化为OpenCV可处理的8位深度图g_c8BitDepth和彩色图imag。这就是我们使用OpenCV进行处理的原始图像,包含了我们所需的全部信息。接着,利用Nifunction()函数将深度图前景分离,利用核心函数picprocess()找到目标球x轴位置point和距离juli,通过串口发送位置point和距离juli信息给上位机,并且我们还使用cvGetTickCount()计算程序处理时间,以便实现对程序的处理性能的监测和优化。

以上是对主函数的介绍,接下来,会对几个关键的子函数进行介绍,从而加深研究的深度。

 

串口收发原理

串口是通过ZQD_ComInit()函数设置的,定义hCom = CreateFile()允许读写,然后打开串口com,设定读超时,写超时,再写入串口超时参数,设定输入输出缓存区参数,获取当前串口状态,然后设置串口参数,具体的参数是波特率9600bps,8位,无奇偶校验,1位停止位,进行到这,com口初始化就完成了。

 

彩色图和深度图原理

利用OpenNI的库函数xContext.Init(),初始化OpenNI驱动 ,创建深度图彩色图生成器DepthGenerator,ImageGenerator,并且设置图像大小XRes=640,nYRes=320,帧频nFPS=30帧,图像对齐,之后开启OpenNI,一切准备好后,进入主循环中,开始更新数据WaitAndUpdateAll(),利用函数GetMetaData()生成彩色图和深度图的原始数据xColorData和xDepthData。这就是我们使用OpenCV进行处理的原始图像,包含了我们所需的全部信息。


图像处理核心部分原理

图像处理的核心函数是Picprocess() ,首先使用Threshold检测深度图阈值化,在深度图中使用OpenCV的函数findContours()找出轮廓,然后利用多边形逼近轮廓加获取矩形和圆形边界框,得到所有Kinect视觉传感器视野中检测到的圆形球的位置和距离信息,其中就包括一个目标球,在对应的彩色图的感兴趣区域ImgROI中计算HSV空间的颜色比例,判断是否是目标球,在找到目标球,得到x轴位置point和距离juli,这两个变量是全局变量,从而实现了对目标球的识别和定位,之后返回主函数继续循环找球。


视觉部分还存在的不足和需要改进之处

在实际的使用中,篮球机器人还存在着以下问题

(1)目标球识别和定位容易受光照,人影等扰动的影响,同时代码运行的速度还可以更快。

(2)参数调试没有可人机交互的界面,只能反复尝试,效率低。

(3)比赛规则中还要求篮球机器人能够自动回位,这点在代码中没有体现出来。

此外,还有其他的问题,比如软件,硬件的升级问题,因此,虽然目前篮球机器人的视觉系统比较完善,但还是存在着不少的问题需要解决。这也是接下来我们着力解决的方向。


附录(程序源码)

#include<iostream>

#include<fstream>

#include<opencv2/core/core.hpp> 

#include<opencv2/highgui/highgui.hpp> 

#include<opencv2/imgproc/imgproc.hpp>

#include<windows.h>

#include<winnt.h>

#include<XnCppWrapper.h>

//#pragma comment( lib,"openni.lib" )

usingnamespace cv;

usingnamespace std;

HANDLE hCom;

int ZQD_ComInit()

{

       hCom= CreateFile(TEXT("COM2"),//COM1

              GENERIC_READ | GENERIC_WRITE, //允许读和写

              0, //独占方式

              NULL,

              OPEN_EXISTING, //打开而不是创建

              0, //同步方式

              NULL);

       if (hCom == (HANDLE)-1)

       {

              MessageBox(NULL, TEXT("打开COM失败"), TEXT("Error"), MB_OK);

              return -1;

       }

       COMMTIMEOUTS TimeOuts;

       //设定读超时

       TimeOuts.ReadIntervalTimeout= 10;

       TimeOuts.ReadTotalTimeoutMultiplier= 20;

       TimeOuts.ReadTotalTimeoutConstant= 20;

       //设定写超时

       TimeOuts.WriteTotalTimeoutMultiplier= 500;

       TimeOuts.WriteTotalTimeoutConstant= 2000;

       // 写入串口超时参数

       if (!SetCommTimeouts(hCom,&TimeOuts))

       {

              MessageBox(NULL, TEXT("写入超时参数错误"), TEXT("Error"), MB_OK);

              return -1;

       }

       // 设置输入输出缓冲区参数,返回非0表示成功

       if (!SetupComm(hCom, 1024, 1024))

       {

              MessageBox(NULL, TEXT("设置串口读写缓冲区失败"), TEXT("Error"), MB_OK);

              return -1;

       }

       DCB dcb;

       // 获取当前串口状态信息(只需要修改部分串口信息),调用失败返回0

       if (!GetCommState(hCom, &dcb))

       {

              MessageBox(NULL, TEXT("获取串口属性失败"), TEXT("Error"), MB_OK);

              return -1;

       }

       dcb.BaudRate= 9600; //波特率为9600

       dcb.ByteSize= 8; //每个字节有8

       dcb.Parity= NOPARITY; //无奇偶校验位

       dcb.StopBits= ONESTOPBIT; //一个停止位

       if (!SetCommState(hCom, &dcb))

       {

              MessageBox(NULL, TEXT("设置串口参数出错"), TEXT("Error"), MB_OK);

              return -1;

       }

       return0;

}

// 全局变量定义及赋值

int point = 0;

int juli = 0;

Mat g_c8BitDepth;

vector<Mat> hsvSplit;

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值