IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 【工程训练/水中机器人】水下管道智能巡检【视觉部分】总结 -> 正文阅读

[人工智能]【工程训练/水中机器人】水下管道智能巡检【视觉部分】总结

【工程训练/水中机器人】水下管道智能巡检【视觉部分】总结

本文为第七届大学生工程训练综合能力竞赛中【水下管道智能巡检赛项】和第十四届国际水中机器人大赛【水下管道智能巡检组】视觉部分总结。


前言

我在队伍中主要负责机器人视觉功能的实现,所以在本篇参赛总结中只会涉及视觉功能实现的思路和过程。


提示:下文中所提出的实现方法不一定是最优解,如果有其他更好的建议和想法,我衷心欢迎大家与我交流,一起学习进步!

一、规则解读

完整规则太多了,这里仅引入一些与视觉部分相关的内容。

水下机器人能够对水下管道上的吸附物进行检测报警及移除清理等,竞赛过程中水下机器人必须全程自主运行。
赛场尺寸(长×宽×高)为 3000×2000×600(mm)长方形水池,示意图如下:
在这里插入图片描述
水下管道铺设在水池内,分浅水区、渐变区和深水区。管道上共设置若干(大于 5、小于 20)个吸附物,分布在管道各处。
熟悉规则后,总结视觉任务如下:

  • 管道巡线
  • 吸附物检测与识别

二、实现思路

1.管道巡线

硬件采用openmv,寻迹对象为水下白色管道,思路与我的另一篇博文:https://blog.csdn.net/qq_39784672/article/details/121239435?spm=1001.2014.3001.5501中寻迹思路相仿,这里就不赘述了。

2.吸附物检测与识别

吸附物在管道上布置方式如下图所示:
在这里插入图片描述
吸附物为实心黑色物体,其截面为正方形、圆形两种,边长或直径尺寸限制在 30~50mm 范围,厚度不大于 30mm。吸附物截面图如下:在这里插入图片描述

上面为第十四届国际水中机器人大赛的比赛规则,工训的规则和这个相差不大。工训中要求检测并识别出吸附物形状;而水中则只需检测出即可,算是降低了难度。

吸附物检测与识别我们采用了两种方案:

(1) openmv手工特征

我们尝试过许多特征,比如色块框像素占比、圆形和矩形查找等。

(2) k210目标检测模型

通过制作吸附物的数据集训练yolo目标检测模型,最终部署到k210上进行预测输出吸附物类型和位置,完成检测和识别任务。
相关实现方法参加我的另一篇博文:【实战】K210训练与部署YOLO目标检测模型

openmv代码

最终比赛代码如下:

import sensor, image, time, pyb
import math
from pyb import UART, Timer

# 返回参数初始化
tube_offset_angle = 0                               # 管道偏移角
tube_offset_distance = 0                            # 管道偏移距离
obstacle_shape = 0                                  # 障碍物形状,取值规则:0:没有障碍物;1:圆形障碍物;2:矩形障碍物
# 调试参数
tube_threshold = (30, 100, -128, 127, -128, 127)     # 管道LAB阈值
obstacle_threshold = (0, 18, -7, 26, -3, 12)    # 障碍物LAB阈值
timer_freg = 25                                     # 定时器触发间隔(Hz)

# 定时器回调函数
def timeFunc(timer):
    time_flag = 1

# 判断障碍块位置
# return: 0:left 1:center 2:right 3:error
def getPosition(o_b, t_b):
    # 计算与管道中心的偏移
    x_offset = (o_b[0] + o_b[2]/2) - (t_b[0] + t_b[2]/2)
#    print(x_offset)
    if abs(x_offset) < ((75 / scale)/5):
        p_flag = 1
    elif x_offset < 0:
        p_flag = 0
    elif x_offset > 0:
        p_flag = 2
    else:
        p_flag = 3
#    print(p_flag)
    return p_flag

def find_max(blobs):
    max_size=0
    for blob in blobs:
        # if blob.pixels()>=250 and blob.pixels()<=7000:
            if blob.pixels() > max_size:
                max_blob=blob
                max_size = blob.pixels()
                return max_blob

sensor.reset()                          # 初始化摄像头
sensor.set_pixformat(sensor.RGB565)     # 格式为 RGB565
sensor.set_framesize(sensor.QQVGA)      # 使用 QQVGA 速度快一些,160*120
sensor.skip_frames(n = 800)             # 跳过800s,使新设置生效,并自动调节白平衡
sensor.set_auto_gain(False)             # 关闭自动自动增益
sensor.set_auto_whitebal(False)
uart = UART(3, 115200)                  # 初始化串口通信参数
clock = time.clock()                    # 追踪帧率
time_flag = 0                           # 定时标志位
timer = Timer(2)                        # 使用定时器2创建一个定时器对象
timer.init(freq=timer_freg)             # 设置触发间隔
timer.callback(timeFunc)                # 定义定时器回调函数
scale = 0                               # 图像比例尺(mm/pixel)

while (True):
    clock.tick()
    img = sensor.snapshot()
    # 识别管道
    tube_blobs = img.find_blobs([tube_threshold], pixels_threshold = 2000)
    if tube_blobs:
        tube_flag = 1
        t_b = find_max(tube_blobs)
        tube_offset_angle = t_b[7]
        tube_offset_distance = t_b[5]
        scale = 75 / t_b[2]
        # print(scale)
        img.draw_rectangle(t_b[0:4])
        # 绘制管道方向线
		# img.draw_line((t_b[5], t_b[6], t_b[5] + int(50 * math.cos(t_b[7])), t_b[6] + int(50 * math.sin(t_b[7]))),color = (255,255,255))
        # 识别障碍物
        obstacle_blobs = img.find_blobs([obstacle_threshold], roi = (t_b[0:4]), pixels_threshold = 100)
        if obstacle_blobs:
            o_b = find_max(obstacle_blobs)
            img.draw_rectangle(o_b[0:4])
            if abs((o_b[1] + o_b[3]/2)-60) < 30*scale:
                # 判断位置
				# img.draw_line(int(o_b[0] + o_b[2]/2),0,int(o_b[0] + o_b[2]/2),120,color = (255,0,0))
				# img.draw_line(int(t_b[0] + t_b[2]/2),0,int(t_b[0] + t_b[2]/2),120,color = (255,0,0))
                p = getPosition(o_b, t_b)
                # 障碍块在中间
                if p == 1:
                    circles = img.find_circles(roi = t_b.rect(),threshold = 3000, x_margin = 10, y_margin = 10, r_margin = 10,
                    r_min = int(10*scale), r_max = int(30*scale))
                    if circles:
                        for c in circles:
							# img.draw_circle(c.x(),c.y(),c.r())
                            obstacle_shape = 1
                    else:
                        obstacle_shape = 2
                # 障碍块在左侧或者右侧,判断方法相同
                elif p == 0 or p == 2:
                    if o_b[3] > 35*scale:
						# print(o_b[3] - 35*scale)
                        obstacle_shape = 2
                    else:
						# print(o_b.density())
                        if o_b.density() < 0.85:
                            obstacle_shape = 1
                        else:
                            obstacle_shape = 2
                # 出错
                else:
                    pass
            else:
                obstacle_shape = 0
        else:
            obstacle_shape = 0
    else:
        tube_flag = 0
        tube_offset_distance = 0
        tube_offset_angle = 0

    # 串口通信
    if time_flag == 0:
        uart.write('D%03dA%03dS%01dE' % (tube_offset_distance, tube_offset_angle * 53, obstacle_shape))
        print('D%03dA%03dS%01dE' % (tube_offset_distance, tube_offset_angle * 53, obstacle_shape))
        time_flag = 0
    # 打印帧率
    # print(clock.fps())

方案总结和分析

上面两种方法中,在工训中使用的是openmv方案。
在这里插入图片描述
Openmv方案对置于管道正上方的吸附物识别正确率较高,一旦吸附物位于管道两侧误识别概率较高,且随着距正中线愈远,概率愈高。这是因为在图像中侧置的黑色吸附圆柱和立方体在低像素和纹理少的情况下根本无法分辨(连人眼都无能为力)。
K210方案检测和识别的效果都很好。但是需要采集大量水下图片并标注,耗时长。(这也是我们为什么采用openmv的原因,时间不够了。)


总结

这两个比赛中,特别是这个水下巡检赛项,千万要读懂规则,制定合理的拿分策略。我们队伍就是被规则坑了,花了过多的时间追求跑完全程的速度,而忽略了识别和检测的重要性(分值占比),导致赛前忙手忙脚。最后,便是电控和视觉得多联调!

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-11-27 09:54:11  更:2021-11-27 09:54:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 4:02:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码