D435相机结合Yolo V8识别出目标物体,并转点云出抓取位姿。

news2025/1/21 2:51:33

最近项目上需要完成整个识别、定位、到最后的抓取流程。
分享一下,通过使用D435相机并结合Yolo V8识别出目标物体后,抠取出目标物体部分的有效深度图,最后将前景物体部分的RGB

D435相机结合Yolo V8识别出目标物体,并转点云出抓取位姿

  • 1、D435相机取流
  • 2、D435结合Yolo V8实时检测
  • 3、扣取指定物体的深度图
    • 3.1 扣取指定物体的mask
    • 3.2 根据mask扣取物体有效深度部分
  • 4、 结合相机内参转物体点云
  • 5、 抓取

1、D435相机取流

使用pyrealsense2进行RGB-D获取视频流,这里最大的坑其实就是每一帧得做一个RGB-D帧间的对齐。

import cv2
import numpy as np
import pyrealsense2 as rs

pipeline = rs.pipeline()
align_to = rs.stream.color
align = rs.align(align_to)
config = rs.config()
D400_imgWidth, D400_imgHeight = 640, 480
config.enable_stream(rs.stream.color, D400_imgWidth, D400_imgHeight, rs.format.bgr8, 30)
config.enable_stream(rs.stream.depth, D400_imgWidth, D400_imgHeight, rs.format.z16, 30)

profile = pipeline.start(config)

while True:
    frames = pipeline.wait_for_frames()
    # RGB-D对齐
    aligned_frames = align.process(frames)
    aligned_color_frame = aligned_frames.get_color_frame()
    aligned_depth_frame = aligned_frames.get_depth_frame()

    if not aligned_depth_frame or not aligned_color_frame:
        raise Exception("[info] No D435 data.")

    rgb = np.asanyarray(aligned_color_frame.get_data())
    d = np.asanyarray(aligned_depth_frame.get_data())

    if len(rgb):
        cv2.imshow("RGB", rgb)
        cv2.imshow("D", rgb)

        if cv2.waitKey(1) & 0xFF == ord("q"):
            break

2、D435结合Yolo V8实时检测

其实就是将D435的RGB流按照循环逐帧送进Yolo V8进行推理
from ultralytics import YOLO

model = YOLO(r"/train/weights/best.pt")
while True:
    frames = pipeline.wait_for_frames()
    aligned_frames = align.process(frames)
    aligned_color_frame = aligned_frames.get_color_frame()
    aligned_depth_frame = aligned_frames.get_depth_frame()

    if not aligned_depth_frame or not aligned_color_frame:
        raise Exception("[info] No D435 data.")

    rgb = np.asanyarray(aligned_color_frame.get_data())
    d = np.asanyarray(aligned_depth_frame.get_data())

    if len(rgb):
        results = model(rgb, conf=0.25)

        annotated_frame = results[0].plot()
        cv2.imshow("YOLOv8 Inference", annotated_frame)

        if cv2.waitKey(1) & 0xFF == ord("q"):
            break

3、扣取指定物体的深度图

3.1 扣取指定物体的mask

正常场景中只有一小部分是我们想要的,比如说一张桌面上有许多物件,但我只想识别、或者后期只抓绿色的杯子。那么就需要将Yolo V8检测出来的所有结果进行后处理,筛出我们想要的物体。

// An highlighted block
'''进行深度学习前向传播推理'''
results = model(color_img, conf=0.25)
# 封装后处理函数,只保留指定“input”的mask。
def backward_handle_output(results , color_img, depth_img, nc, input):
    center = None
    cls = []
    mapped_depth = None
    annotated_frame = output[0].plot()
    mask = None
    # 如果检测到物体,也就是mask不为空时
    if results [0].masks is not None:
        # 获取所有检测框所属的类别 
        for cls_idx in range(len(output[0].boxes)):
            cls.append(output[0].names.get(int(output[0].boxes.cls[cls_idx].item())))
        # 只留下指定的“input”类别物体
        if input in cls:
            # 根据“input”对应的索引号,获取其mask
            cls_idx = cls.index(input)
            mask = np.array(output[0].masks.data.cpu())[cls_idx] 

3.2 根据mask扣取物体有效深度部分

正常会通过深度图结合相机内参来转点云,所以如果我们只想要将我们待检测的物体部分的深度图转成点云图,那这样就可以过滤掉不相关的物体或背景。

# 判断非指定物体的有效区域
channel_zeros = mask == 0
'''初始化一个与原始深度图类型的一致的全0深度图'''
mapped_depth = np.zeros_like(depth_img)
'''也就是我们指定“input”物体mask区域对应的位置的深度信息抠出来,剩下非物体有效区域深度值全置为0'''
# 这样,我们就成功晒出了物体部分的深度值,其余全为背景0。
mapped_depth[~channel_zeros] = depth_img[~channel_zeros]
mapped_depth[channel_zeros] = 0

4、 结合相机内参转物体点云

import open3d as o3d
pcd = o3d.geometry.PointCloud()

def create_point_cloud_from_depth_image(depth, camera, organized=True):
    """ Generate point cloud using depth image only.

        Input:
            depth: [numpy.ndarray, (H,W), numpy.float32]
                depth image
            camera: [CameraInfo]
                camera intrinsics
            organized: bool
                whether to keep the cloud in image shape (H,W,3)

        Output:
            cloud: [numpy.ndarray, (H,W,3)/(H*W,3), numpy.float32]
                generated cloud, (H,W,3) for organized=True, (H*W,3) for organized=False
    """
    assert(depth.shape[0] == camera.height and depth.shape[1] == camera.width)
    xmap = np.arange(camera.width)
    ymap = np.arange(camera.height)
    xmap, ymap = np.meshgrid(xmap, ymap)
    points_z = depth / camera.scale
    points_x = (xmap - camera.cx) * points_z / camera.fx
    points_y = (ymap - camera.cy) * points_z / camera.fy
    cloud = np.stack([points_x, points_y, points_z], axis=-1)
    if not organized:
        cloud = cloud.reshape([-1, 3])
    return cloud
    
if mapped_depth is not None:
    mapped_depth = mapped_depth.astype(float) / 1000.0
    depth_img = depth_img.astype(float) / 1000.0

    mask_cloud = create_point_cloud_from_depth_image(mapped_depth, camera, organized=True)

    depth_range = [0.0, 1.5]
    mask = (depth_img < depth_range[1]) & (depth_img > depth_range[0])

    obj_cloud_masked = mask_cloud[mask]
    rgb_masked = color_img[mask] / 255

    idxs = np.random.choice(len(cloud_masked), 20000, replace=True)

    obj_cloud_sampled = obj_cloud_masked[idxs]
    rgb_sampled = rgb_masked[idxs]


    pcd.points = o3d.utility.Vector3dVector(obj_cloud_sampled.astype(np.float32))
    pcd.colors = o3d.utility.Vector3dVector(rgb_sampled.astype(np.float32))

    # 如果可视化的点云方向不正,可进行坐标系方向调整
    # obj_cloud_sampled[:, 1] = - obj_cloud_sampled[:, 1]
    # obj_cloud_sampled[:, 2] = - obj_cloud_sampled[:, 2]


    o3d.visualization.draw_geometries([pcd])

5、 抓取

如果相对整个场景进行感知抓取,而非指定单个物体,就可以把根据物体mask扣取深度图部分取消。进而,使用开源GraspNet、AnyGrasp等抓取网络进行抓取姿势预测。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1789932.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt之api的调用问题

1.调用api过程中&#xff0c;出现如下报错内容 先写一个测试样例 import openaiopenai.api_key "OPEN_AI_KEY" openai.api_base"OPEN_AI_BASE_URL" # 是否需要base根据自己所在地区和key情况进行completion openai.ChatCompletion.create(model"g…

空调外机清洁机器人设计

现在的空调&#xff0c;有很多安装在高层&#xff0c;一旦安装使用后&#xff0c;外机几乎不可能再清洗。因为费用高&#xff0c;清洁工人的钱应该是好几百还不止&#xff1b;清洁风险高&#xff0c;空调师傅需要高空作业&#xff0c;如果发生意外业主难以承担。但空调运行几年…

2024年分布式存储技术趋势:高性能、灵活架构与广泛应用

在数据驱动的世界中&#xff0c;存储技术的进步对于支撑现代企业和社会的数字化需求至关重要。2024年&#xff0c;分布式存储技术的发展呈现出一系列令人兴奋的趋势&#xff0c;预示着存储行业的未来走向。让我们一起探索这些关键趋势&#xff0c;并了解它们如何塑造我们的数据…

陆面生态水文模拟与多源遥感数据同化的实践技术应用

了解陆表过程的主要研究内容以及陆面模型在生态水文研究中的地位和作用&#xff1b;熟悉模型的发展历程&#xff0c;常见模型及各自特点&#xff1b;理解Noah-MP模型的原理&#xff0c;掌握Noah-MP模型在单站和区域的模拟、模拟结果的输出和后续分析及可视化等方法&#xff1b;…

Servlet详解(下)

目录 一、Servlet详解1.1、核心接口和类1.1.1、Servlet接口1.1.2、GenericServlet1.1.3、HttpServlet(推荐) 1.2、两种配置方法1.2.1、使用web.xml1.2.2、使用注解 二、Servlet应用2.1、request对象2.2、request主要方法2.2、response对象2.3、response主要方法 三、转发与重定…

LangChain框架介绍

LangChain 的核心组件 模型 I/O 封装 LLMs&#xff1a;大语言模型Chat Models&#xff1a;一般基于 LLMs&#xff0c;但按对话结构重新封装PromptTemple&#xff1a;提示词模板OutputParser&#xff1a;解析输出 数据连接封装 Document Loaders&#xff1a;各种格式文件的加载…

大数据数据治理

大数据数据治理介绍 大数据数据治理是一个复杂的过程&#xff0c;涉及到数据的标准化、融通、关联、解析、聚合等一系列活动。其核心目标是在确保数据安全的基础上&#xff0c;提高大数据资源和资产的可用性、易用性和可靠性&#xff0c;从而显著提升大数据资源和资产的价值7。…

【阿里前端面试题】聊聊前端性能优化的方案,解决过什么样的性能问题?

大家好&#xff0c;我是“寻找DX3906”。每天进步一点。日积月累&#xff0c;有朝一日定会厚积薄发&#xff01; 前言&#xff1a; 前面已经和大家分享了4篇面试题&#xff1a; 《【阿里前端面试题】浏览器的加载渲染过程》 《【阿里前端面试题】客户端和服务器交互&#xff…

店匠科技亮相VivaTech,新零售解决方案引关注

在中法建交60周年之际,两国关系持续发展并共同推动双方在人工智能和全球治理领域达成重要合作。同时,浙江-法国高新产业创新合作对接会在巴黎顺利举行,进一步促进了中法两国在高新技术领域的交流与合作。 紧跟此次访问的步伐,众多中国科技创新企业齐聚巴黎,于5月22日至25日在法…

热更新简述

只要实现了进程级别的无状态(或在重启时恢复状态),除了跨过"重启期间"的连接会受到影响这个问题之外,我们还可以通过重启进程的方式实现热更新 优雅的进程切换 在热更新期间,新旧经常会同时运行,旧进程处理旧的请求,等处理完全部请求之后,再退出,而新进程则负责处理…

通用多物理场仿真PaaS平台伏图(Simdroid)5.0发布 | 试用

伏图&#xff08;Simdroid&#xff09;是云道智造自主研发的通用多物理场仿真PaaS平台&#xff0c;历经十年打磨&#xff0c;已迭代至5.0版本&#xff0c;实现“工程可用”。 通用多物理场仿真PaaS平台伏图(Simdroid)5.0 伏图5.0具备自主可控的固体力学、流体力学、电动力学、热…

个人参与场外期权交易的最全指南

个人参与场外期权交易的最全指南 一、引言 场外期权作为金融市场中的一大亮点&#xff0c;为个人投资者提供了多样化的风险管理及投资策略选择。本文将详细探讨个人如何安全、有效地参与场外期权交易。 文章来源/&#xff1a;财智财经 二、理解场外期权 场外期权是双方通过协…

CSS双飞翼布局

双飞翼布局是一种经典的CSS布局模式&#xff0c;主要用于实现左右两列固定宽度&#xff0c;中间列自适应的布局。 比如&#xff1a;写一个左中右布局占满全屏&#xff0c;其中左、右两块固定宽 200px&#xff0c;中间自适应&#xff0c;要求先加载中间块。 <!DOCTYPE html…

智能工厂总体设计方案

近年来&#xff0c;中国制造业长久以来依靠的劳动力优势正在逐步丧失。廉价的劳动力大军&#xff0c;曾是中国制造业发展的主动力&#xff0c;如今已不如往昔那么庞大和廉价&#xff0c;企业还面临不断恶化的用工短缺问题。因此&#xff0c;对于大规模制造生产&#xff0c;并想…

【langchain手把手3】使用示例选择器构建Prompt

【langchain手把手3】使用示例选择器构建Prompt Example selector 示例选择器实现用于选择示例以将其包括在提示中的逻辑。这使我们能够选择与输入最相关的示例。core内置的有以下3种示例选择器&#xff1a; LengthBasedExampleSelector&#xff1a;MaxMarginalRelevanceExamp…

【leetcode--文本对齐(还没整理完)】

根据题干描述的贪心算法&#xff0c;对于每一行&#xff0c;我们首先确定最多的是可以放置多少单词&#xff0c;这样可以得到该行的空格个数&#xff0c;从而确定该行单词之间的空格个数。 根据题目中填充空格的细节&#xff0c;我们分以下三种情况讨论&#xff1a; 当前行是…

JVM学习-详解类加载器(一)

类加载器 类加载器是JVM执行类加载机制的前提 ClassLoader的作用 ClassLoader是Java的核心组件&#xff0c;所有的Class都是由ClassLoader进行加载的&#xff0c;ClassLoader负责通过各种方式将Class信息的二进制数据流读入JVM内部&#xff0c;转换为一个与目标类型对应的ja…

大模型时代的具身智能系列专题(九)

NYU Lerrel Pinto团队 Lerrel Pinto是NYU Courant的计算机科学助理教授&#xff0c;也是用机器人和人工智能实验室(CILVR小组)的一员。在加州大学伯克利分校读博士后&#xff0c;在CMU机器人研究所读博士&#xff0c;在印度理工学院古瓦哈蒂读本科。研究目标是让机器人在我们生…

SpringBoot项目实现自定义注解方式的接口限流

一&#xff0c;实现原理 该限流方式使用的是令牌桶算法&#xff0c;令牌桶算法是基于漏桶算法的一种改进&#xff0c;主要在于令牌桶算法能够在限制服务调用的平均速率的同时&#xff0c;还能够允许一定程度内的突发调用。 系统以固定的速率向桶中添加令牌当有请求到来时&#…