上一篇相关博文,准备阶段OpenMV学习笔记链接:https://sublimerui.top/archives/f10b0e1a.html
无人机题目分析
今年的电赛题目着实让人觉得出题挺新颖的。新颖的同时,困难度就直线提升了(呜呜呜,我们队就是受害者之一,说好的光流可以定点呢,结果那种灰白条纹地面根本就定不住,真的想狠狠地吐槽一下砖家组)
哎,做下来大部分时间懵逼,都是一把辛酸一把泪呀~
言归正传,今年的电赛无人机题目B题——巡线机器人,具体要求是让我们的无人机从一个杆起飞,沿着线飞向宁一个杆,飞行过程中会拍摄条形码和二维码,绕杆一圈后,再降落。题目如下:
PS:这里附上2019年电赛的各方向题目,已经放在Github上:2019电赛题目.zip
分类
题目中,涉及OpenMV的部分,主要可以分为以下几类吧:
- 识别并拍摄条形码和二维码,储存于SD卡中;
OpenMV巡线(此方法是由于实际比赛中发现无法用光流在灰白条纹地面上定点,即无法控制其水平方向的误差偏移)
- 方法一:识别并拟合两条杆之间线缆的直线,返回偏差距离和偏差角度(缺点:OpenMV视野横向不丢失距离太小了);
- 方法二:拟合识别条纹边缘(由于条纹宽度规定了,可以寻找灰白条纹和外部白色地面的交界处),拟合出边缘直线,返回偏差距离和偏差角度(相对来说更稳定,这也是我们队最后用的方法);
- 识别并返回环形圆板中心红点坐标位置,使飞机定圆点(发挥部分)
- 其他(例如起飞后用OpenMV识别靠杆,识别到特定标志后开始绕杆等等)
逐类型分析
拍摄条形码和二维码并储存SD卡
有关于条形码和二维码的讲解我已将在上一篇博文中有所总结和归纳了,这里,直接贴上我写的部分代码吧,全部代码已经放在我的Github上面了,需要的话可以自己下载呐~
自己手写的完整程序已放在Github上:shot_images_to_save.py
- 条形码和二维码拍摄:
函数shot_images_while_tracking_lines()
用于拍摄并储存找 照片于SD卡中。其中,此段程序会分别对条形码连续循环拍3三张,分别命名为“barcod_1.jpg”,“barcod_2.jpg”和“barcod_3.jpg”(二维码同理),只要OpenMV插上了SD卡后,一旦识别到相关条码后,便会拍摄并自动保存到卡中。
完整程序代码中,如果识别到条形码,OpenMV就会闪绿灯拍照;识别到二维码后,OpenMV会闪红灯拍照。
- 识别条形码(识别黄色)和二维码(二值化后计算像素点,设置阈值):
此段程序中,函数count_pixels_with_movement(img)
用于识别并判断识别条形码和二维码的条件和阈值。以条形码为例,这里通过色块识别的方法,调用img.find_blobs()
函数,通过设置黄色阈值,达到识别到黄色条码的目的。其中,barcode_pixels_threshold
是一个列表,储存的2个元素分别是黄色阈值下限和上限。
此外,我也尝试运用统计像素点的方式去识别二维码和条形码(这里已经被注释掉),其方法是先将图像按照一定的阈值二值化后,调用img.get_pixel()
函数,统计满足像素值为255(即白色)的像素个数,同时,设定特定的像素阈值(如qrcode_pixels_threshold
等等,与黄色检测同理,也有阈值上下限两个阈值),也可以达到同样的效果。
OpenMV巡线
自己手写的完整程序已放在Github上:detect_and_track_edges.py
方法一(拟合两杆间直线)
巡线的时候,使用的是最小二乘法的线性回归算法,即运用img.get_regression()
函数(这里打开了鲁棒算法robust = True
,效果更好),计算其拟合直线后的结果,并拥有两个返回值(误差偏离值singleline_check.flag2.rho()
和偏角值singleline_check.flag2.theta()
)
拟合示意图如下,(其中,红色的为拟合直线):
PS:此方法准确度较高,但是OpenMV图像视野范围有限。当直线从图像视野最下端到达最上端,换算成无人机横向移动的距离仅有5-10cm,当无人机超出此范围时,将无法获取直线了,有一定的局限性。
方法二(拟合识别条纹边缘)
此函数track_edges(img)
中,同样使用img.find_blobs()
找色块的方法,其中运用了简单角度和距离的计算方法。并返回条纹底色边界线的拟合直线,此函数的计算结果为拟合直线距离画面左边界距离rho
和中心线的偏离角度theta
。
拟合示意图如下(其中,红色的为拟合直线):
这样,当检测到条纹边界的时候,会计算拟合出条纹边界的直线。
PS:注意,使用这种方法一定要打开白平衡和自动增益!!!非常重要!!!我们队就吃了这样的亏,使得OpenMV距离地面较近的时候识别正常,一旦远离地面一定距离后,图像中将无法识别边界直线!!!
飞机悬停定圆点
定特定颜色的原点时,将运用img.find_blobs()
函数(这里将图像二值化了),返回色块其中心坐标cx()
和cy()
即可。对于不同的颜色的色块(如题目中的红色),需要实地测试得到不同的阈值。
这里的返回值为圆点中心坐标、像素大小和标志位。
自己手写的完整程序已放在Github上:main.py
找圆点函数:
剩下的其他功能自己就没有写啦(T_T),比赛四天太紧张了,这样已经很不错了,已经是全部成果~
感谢你的耐心阅读呀(๑◡๑),原创总结不易,收藏并评论一下呗~
你的支持就是我前进的动力呀~