【D435i深度相机YOLO V5结合实现目标检测】

本文涉及的产品
资源编排,不限时长
简介: 【D435i深度相机YOLO V5结合实现目标检测】

1. 前言

本文下述使用参考的的工程均来自于下面的两个github

yolo v5参考的代码:https://github.com/ultralytics/yolov5

本文参考的代码(仅获得深度):https://github.com/killnice/yolov5-D435i

Ubuntu环境搭建

【经典Ubuntu20.04版本U盘安装双系统教程】

【Windows10安装或重装ubuntu18.04双系统教程】

【Ubuntu同步系统时间】

【Ubuntu中截图工具】

【Ubuntu安装QQ】

【Ubuntu安装后基本配置】

【Ubuntu安装后基本配置】

【Ubuntu启动菜单的默认项】

【ubuntu系统中修改hosts配置】

【18.04Ubuntu中解决无法识别显示屏】

【ROS 开发神器 Visual Studio Code 的安装和设置】

【基于Ubuntu18.04+Melodic的realsense D435安装】

【Ubuntu18配置Anaconda深度学习环境】

【D435i深度相机YOLO V5结合实现目标检测】

ROS学习笔记

【1. Ubuntu18.04安装ROS Melodic】

【2. 在Github上寻找安装ROS软件包】

【3. 初学ROS,年轻人的第一个Node节点】

【4. ROS的主要通讯方式:Topic话题与Message消息】

【5. ROS机器人的运动控制】

【6. 激光雷达接入ROS】

【7. ROS 中的 IMU 惯性测量单元消息包】

上一个github代码,csdn上的讲解:【Ubuntu18.04使用yolov5教程】


我的文件是在yolov5-D435i工程基础上改的,yolov5-D435i是在yolov5工程基础上改的,源码部分参考了冰激凌啊,D435i深度相机YOLO V5结合实现目标检测部分采用彩色图和深度图对齐,根据彩色图进行YOLO V5识别,输出相对于相机坐标系的目标物体中心点的三维坐标。

2 分析

主要思路是采用彩色图形用yolo检测,深度图对齐,最后输出检测目标物体及相对位置结果。


2.1 关于yolo部分



https://github.com/ultralytics/yolov5 这是一个比较经典的yolo v5的代码,它提供了一些接口,在README.md中进行了介绍。
可以看到只要在自己写的文件里创建model就可以调用这个结果了。



import torch
# Model
model = torch.hub.load('ultralytics/yolov5', 'yolov5s')  # or yolov5m, yolov5l, yolov5x, custom
# Images
img = 'https://ultralytics.com/images/zidane.jpg'  # or file, Path, PIL, OpenCV, numpy, list
# Inference
results = model(img)
# Results
results.print()  # or .show(), .save(), .crop(), .pandas(), etc.


2.2 关于获取三维坐标的部分



❤ https://github.com/killnice/yolov5-D435i里main_debug.py文件的深度获取方法是在中心点附近取一些随机点,
然后深度排序取中值滤波。(这些被随机选择到的中心点,在图中画了蓝色小圆圈标记这些点)猜测这样做是可以避免
realsense获取深度过程中,某点的忽然转换失效,认为深度值为0,如果取周围几个点进行获取深度,并中值滤波,将
大大提高这个深度值在测量过程中的稳定性,避免了realsense忽然某帧某点的深度值为0的情况。
❤ 我要获得中心点的坐标,可以参考Ubutntu下使用realsense d435i(二):获取某二维像素点的三维坐标修改get_mid_pos()函数,根据中心点的坐标以及中心点对应的深度获取中心点的三维坐标。
但是这样做也面临一个问题,就是上面提到的,仅仅测量中心点的深度,当忽然这个深度值为0,他的三维坐标转换就会出错,如果把这个值设为机械臂的目标点,就会导致机械臂一瞬间点的位置出错。
把realsense相机画面的频率降低会对这个现象改善一点,但还是存在,所以考虑可以参考上述深度值得解决办法,也获取周围点,做一个中值滤波。
另外就是考虑相机还没有标定,参考realsense d435相机标定,现在确实照墙壁时深度图像有很多“黑洞”,这有可能也是忽然深度值为0的原因。
❤ 未来要修改的地方
① 把【像素x,像素y,深度值z】进行一个数据结构的保存(是选择元祖、数组还是什么结构还没有想好)
② 利用随机数获取周边的一些点,同样获得这些点的【像素x,像素y,深度值z】
③ 把所有点根据深度值z进行排序和中值滤波,选择排序中间的那一个点,根据深度值以及与其对应的像素x,y,获得该点的三维坐标,并以此为目标物的三维坐标。

2.3 关于文件结构部分



由于yolo的测试程序以及对外开放了接口,所以我们只需要在原来的YOLO v5中(https://github.com/ultralytics/yolov5),再创建一个my_realsense_detect.py程序(不需要替换原来的detect.py程序),就可以了。
也就是说,把my_realsense_detect.py程序放到最开始提到的2个github程序中都可以运行。如果想放到其他的yolo程序,需要看看他具体提到的模型接口,结果接口都是什么。

3. 代码

首先我下载了https://github.com/killnice/yolov5-D435i


我的文件是在yolov5-D435i工程基础上改的,yolov5-D435i是在yolov5工程基础上改的。




git clone https://github.com/killnice/yolov5-D435i.git d435i_yolo
code d435i_yolo/
选择环境参考:https://blog.csdn.net/vor234/article/details/130480581
pip install -r requirements.txt
pip install pyrealsense2
python main_debug.py

然后是在main_debug.py文件的基础上进行了修改,并把它重命名为了d435i_detect.py


说明:

在yolov5-D435i工程中的main.py、main_debug.py和try.py都是可以删除的,只要运行d435i_detect.py就可以

在yolov5工程中,只要把my_realsense_detect.py文件复制进去就也可以运行啦

接下来是我的代码,具体可以根据yolov5-D435i工程中的main_debug.py文件进行修改。

import pyrealsense2 as rs
import numpy as np
import cv2
import random
import torch
import time
# model = torch.hub.load('ultralytics/yolov5', 'yolov5s')
#
model = torch.hub.load('ultralytics/yolov5', 'yolov5l6')
model.conf = 0.5
def get_mid_pos(aligned_depth_frame,box):
    mid_pixel = [(box[0] + box[2])//2, (box[1] + box[3])//2] #确定索引深度的中心像素位置
    # 注意mid_pixel是float,但是get_distance()的参数需要是int
    [x, y] = [int(mid_pixel[0]), int(mid_pixel[1])]
    depth_intrin = aligned_depth_frame.profile.as_video_stream_profile().intrinsics # 获取相机深度参数
    dis = aligned_depth_frame.get_distance(x, y)        # 获取该像素点对应的深度
    # print ('depth: ',dis)       # 深度单位是m
    camera_coordinate = rs.rs2_deproject_pixel_to_point(depth_intrin, [x, y], dis)
    # print ('camera_coordinate: ',camera_coordinate)
    return camera_coordinate
def dectshow(org_img, boxs,aligned_depth_frame):
    img = org_img.copy()
    for box in boxs:
        cv2.rectangle(img, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), (0, 255, 0), 2)
        point_3d = dist = get_mid_pos(aligned_depth_frame,box)
        [x, y, z] = point_3d
        # cv.putText 图片,添加的文字,左上角坐标,字体,字体大小,颜色,字体粗细
        cv2.putText(img, box[-1] + ' (' + str(x)[:4] + ',' + str(y)[:4] + ',' + str(z)[:4] + ')',
                    (int(box[0]), int(box[1])), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 1)
    cv2.imshow('dect_img', img)
if __name__ == "__main__":
    # Configure depth and color streams
    pipeline = rs.pipeline()
    config = rs.config()
    config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 60)
    config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 60)
    # Start streaming
    pipe_profile = pipeline.start(config)
    try:
        while True:
            # # Wait for a coherent pair of frames: depth and color
            # frames = pipeline.wait_for_frames()
            # depth_frame = frames.get_depth_frame()
            # color_frame = frames.get_color_frame()
            # if not depth_frame or not color_frame:
            #     continue
            # # Convert images to numpy arrays
            # depth_image = np.asanyarray(depth_frame.get_data())
            # color_image = np.asanyarray(color_frame.get_data())
            # Depth scale - units of the values inside a depth frame, i.e how to convert the value to units of 1 meter
            # 获取深度传感器的深度标尺(参见rs - align示例进行说明)
            depth_sensor = pipe_profile.get_device().first_depth_sensor()
            depth_scale = depth_sensor.get_depth_scale()
            # print("Depth Scale is: ", depth_scale)      # ('Depth Scale is: ', 0.0010000000474974513)
            # 创建对齐对象与color流对齐
            # align_to 是计划对齐深度帧的流类型
            align_to = rs.stream.color
            # rs.align 执行深度帧与其他帧的对齐
            align = rs.align(align_to)
            ''' 
            获取图像帧与相机参数
            '''
            # 等待获取图像帧,获取颜色和深度的框架集
            frames = pipeline.wait_for_frames()         # frames.get_depth_frame()是640x360深度图像
            # 获取对齐帧,将深度框与颜色框对齐
            aligned_frames = align.process(frames)
            # 获取对齐帧中的的depth帧
            aligned_depth_frame = aligned_frames.get_depth_frame() # aligned_depth_frame是640x480深度图像
            # 获取对齐帧中的的color帧
            aligned_color_frame = aligned_frames.get_color_frame()
            # 将images转为numpy arrays
            # RGB图
            color_image = np.asanyarray(aligned_color_frame.get_data())
            # 深度图(默认16位)
            depth_image = np.asanyarray(aligned_depth_frame.get_data())
            results = model(color_image)
            boxs= results.pandas().xyxy[0].values
            #boxs = np.load('temp.npy',allow_pickle=True)
            dectshow(color_image, boxs, aligned_depth_frame)
            # Apply colormap on depth image (image must be converted to 8-bit per pixel first)
            depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.03), cv2.COLORMAP_JET)
            # Stack both images horizontally
            images = np.hstack((color_image, depth_colormap))
            # Show images
            cv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)
            cv2.imshow('RealSense', images)
            key = cv2.waitKey(1)
            # Press esc or 'q' to close the image window
            if key & 0xFF == ord('q') or key == 27:
                cv2.destroyAllWindows()
                break
    finally:
        # Stop streaming
        pipeline.stop()


运行效果如下:


1.png

这个程序需要说明的是像素坐标的中点是float形式,而get_distance(x, y)函数的参数是int形式,需要进行强制转换。

相关实践学习
使用ROS创建VPC和VSwitch
本场景主要介绍如何利用阿里云资源编排服务,定义资源编排模板,实现自动化创建阿里云专有网络和交换机。
阿里云资源编排ROS使用教程
资源编排(Resource Orchestration)是一种简单易用的云计算资源管理和自动化运维服务。用户通过模板描述多个云计算资源的依赖关系、配置等,并自动完成所有资源的创建和配置,以达到自动化部署、运维等目的。编排模板同时也是一种标准化的资源和应用交付方式,并且可以随时编辑修改,使基础设施即代码(Infrastructure as Code)成为可能。 产品详情:https://www.aliyun.com/product/ros/
目录
相关文章
|
14天前
|
机器学习/深度学习 编解码 算法
什么是超分辨率?浅谈一下基于深度学习的图像超分辨率技术
超分辨率技术旨在提升图像或视频的清晰度,通过增加单位长度内的采样点数量来提高空间分辨率。基于深度学习的方法,如SRCNN、VDSR、SRResNet等,通过卷积神经网络和残差学习等技术,显著提升了图像重建的质量。此外,基于参考图像的超分辨率技术通过利用高分辨率参考图像,进一步提高了重建图像的真实感和细节。
|
2月前
|
机器学习/深度学习 并行计算 PyTorch
图像检测【YOLOv5】——深度学习
Anaconda的安装配置:(Anaconda是一个开源的Python发行版本,包括Conda、Python以及很多安装好的工具包,比如:numpy,pandas等,其中conda是一个开源包和环境管理器,可以用于在同一个电脑上安装不同版本的软件包,并且可以在不同环境之间切换,是深度学习的必备平台。) 一.Anaconda安装配置. 1.首先进入官网:https://repo.anaconda.com,选择View All Installers. 2.打开看到的界面是Anaconda的所以安装包版本,Anaconda3就代表是Python3版本,后面跟的是发行日期,我选择了最近的2022
69 28
|
4月前
|
机器学习/深度学习 数据采集 自动驾驶
深度学习之相机内参标定
相机内参标定(Camera Intrinsic Calibration)是计算机视觉中的关键步骤,用于确定相机的内部参数(如焦距、主点位置、畸变系数等)。传统的标定方法依赖于已知尺寸的标定板,通常需要手动操作,繁琐且耗时。基于深度学习的方法则通过自动化处理,提供了一种高效、准确的内参标定方式。
228 13
|
4月前
|
机器学习/深度学习 编解码 算法框架/工具
使用Python实现深度学习模型:图像超分辨率与去噪
【7月更文挑战第17天】 使用Python实现深度学习模型:图像超分辨率与去噪
140 4
|
4月前
|
机器学习/深度学习 计算机视觉
YOLOv10实战:红外小目标实战 | 多头检测器提升小目标检测精度
本文改进: 在进行目标检测时,小目标会出现漏检或检测效果不佳等问题。YOLOv10有3个检测头,能够多尺度对目标进行检测,但对微小目标检测可能存在检测能力不佳的现象,因此添加一个微小物体的检测头,能够大量涨点,map提升明显; 多头检测器提升小目标检测精度,1)mAP50从0.666提升至0.677
914 3
|
5月前
|
开发者
UniAD 加入 Lidar 模态
解决2:检测和跟踪需要分开训练。uniad 原作者使用的是 bevformer 预训练的检测权重。因此,先要写一个检测代码,作单帧检测任务。然后将训练好的检测权重 load 到跟踪的代码中。
65 0
|
机器学习/深度学习 传感器 编解码
史上最全 | BEV感知算法综述(基于图像/Lidar/多模态数据的3D检测与分割任务)
以视觉为中心的俯视图(BEV)感知最近受到了广泛的关注,因其可以自然地呈现自然场景且对融合更友好。随着深度学习的快速发展,许多新颖的方法尝试解决以视觉为中心的BEV感知,但是目前还缺乏对该领域的综述类文章。本文对以视觉为中心的BEV感知及其扩展的方法进行了全面的综述调研,并提供了深入的分析和结果比较,进一步思考未来可能的研究方向。如下图所示,目前的工作可以根据视角变换分为两大类,即基于几何变换和基于网络变换。前者利用相机的物理原理,以可解释性的方式转换视图。后者则使用神经网络将透视图(PV)投影到BEV上。
史上最全 | BEV感知算法综述(基于图像/Lidar/多模态数据的3D检测与分割任务)
|
机器学习/深度学习 算法 计算机视觉
旋转目标检测【1】如何设计深度学习模型
平常的目标检测是平行的矩形框,“方方正正”的;但对于一些特殊场景(遥感),需要倾斜的框,才能更好贴近物体,旋转目标检测来啦~
553 0
|
6月前
|
机器学习/深度学习 编解码 自然语言处理
CVPR 2022 | Restormer:高分辨率图像恢复的高效Transformer
CVPR 2022 | Restormer:高分辨率图像恢复的高效Transformer
433 1
|
6月前
|
传感器 机器学习/深度学习 自动驾驶
【多模态融合】CRN 多视角相机与Radar融合 实现3D检测、目标跟踪、BEV分割 ICCV2023
本文介绍使用雷达与多视角相机融合,实现3D目标检测、3D目标跟踪、道路环境BEV分割,它是来自ICCV2023的。CRN,全称是Camera Radar Net,是一个多视角相机-雷达融合框架。 通过融合多视角相机和雷达的特性,生成语义丰富且空间精确的BEV特征图。实现3D物体检测、跟踪和BEV分割任务。
514 1