使用深度相机D435i+YOLOv8实现物体三维坐标实时显示

一、获取相机内参

下列指令为获取相机内参指令,输入此指令前需要获得相机的深度帧和彩色帧数据。

如何使用vsCode打开intel D435i深度相机

# 获取相机内参
depth_intrinsics = depth_frame.profile.as_video_stream_profile().intrinsics
color_intrinsics = color_frame.profile.as_video_stream_profile().intrinsics
# 命令行打印相机内参显示
print("Depth Intrinsics:", depth_intrinsics)
print("Color Intrinsics:", color_intrinsics)

显示结果为:

Depth Intrinsics: [ 640x480  p[322.02 236.768]  f[391.288 391.288]  Brown Conrady [0 0 0 0 0] ]
Color Intrinsics: [ 640x480  p[328.884 240.065]  f[606.697 606.756]  Inverse Brown Conrady [0 0 0 0 0] ]

其中:640x480是像素宽度x像素高度; p[322.02 236.768]为主点(镜头光轴与图像平面的交点)的坐标; f[391.288 391.288]为焦距参数;Brown Conrady [0 0 0 0 0]分别表示畸变模型与畸变系数

二、关于 result.boxes.xywh.tolist()的xywh的解释

关于boxes = result.boxes.xywh.tolist(),可以在result源码里面找到相关的定义如下,可以看出相应的x,y为中心点坐标,w为宽度,h为高度

三、自动根据相机内参和xywh计算相应的深度数据

首先通过下列指令获取绘制的边框信息,包括中心点坐标x,y和边框宽度w,边框高度h

然后通过中心点的坐标计算相应点的深度距离,并利用rs.rs2_deproject_pixel_to_point(相机深度内参,点坐标,点深度)将其转化为相机坐标系下的x,y,z;最后实现单位转化,显示为以mm为单位的数据。

四、代码与结果展示

详细代码文件如下:

# 此程序用于实现视频分帧识别物体,并为所识别的物品添加矩形框,显示置信度、标签等,更新于2024/6/24
# 更新程序,用于显示实时三维坐标2024/6/24
import cv2
import numpy as np
import pyrealsense2 as rs
from ultralytics import YOLO  # 将YOLOv8导入到该py文件中# 加载官方或自定义模型
model = YOLO(r"E:\Deep learning\YOLOv8\yolov8n.pt")  # 加载一个官方的检测模型
# model = YOLO(r"E:\Deep learning\YOLOv8\yolov8s.pt")  # 加载一个官方的检测模型
# model = YOLO(r"E:\Deep learning\YOLOv8\yolov8n-seg.pt")  # 加载一个官方的分割模型
# model = YOLO(r"E:\Deep learning\YOLOv8\yolov8n-pose.pt")  # 加载一个官方的姿态模型# 深度相机配置
pipeline = rs.pipeline()  # 定义流程pipeline,创建一个管道
config = rs.config()  # 定义配置config
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)  # 初始化摄像头深度流
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
pipe_profile = pipeline.start(config)  # 启用管段流
align = rs.align(rs.stream.color)  # 这个函数用于将深度图像与彩色图像对齐def get_aligned_images():  # 定义一个获取图像帧的函数,返回深度和彩色数组frames = pipeline.wait_for_frames()  # 等待获取图像帧aligned_frames = align.process(frames)  # 获取对齐帧,将深度框与颜色框对齐depth_frame = aligned_frames.get_depth_frame()  # 获取深度帧color_frame = aligned_frames.get_color_frame()  # 获取对齐帧中的的color帧depth_image = np.asanyarray(depth_frame.get_data())  # 将深度帧转换为NumPy数组color_image = np.asanyarray(color_frame.get_data())  # 将彩色帧转化为numpy数组# 获取相机内参# 获取深度内参depth_intri = depth_frame.profile.as_video_stream_profile().intrinsics# 获取彩色内参color_intri = color_frame.profile.as_video_stream_profile().intrinsics# 命令行输出内参检查# print("Depth Intrinsics:",depth_intri)# print("Color Intrinsics:",color_intri)# cv2.applyColorMap()将深度图像转化为彩色图像,以便更好的可视化分析depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.07), cv2.COLORMAP_JET)# 返回深度内参、对齐深度帧、彩色图像return depth_intri, depth_frame, color_imageif __name__ == '__main__':try:while True:depth_intri, depth_frame, color_image = get_aligned_images()  # 获取深度帧和彩色帧source = [color_image]# 轨迹追踪,persist=true表示数据储存# results = model.track(source, persist=True)results = model.predict(source, save=False)# 预测完后打印目标框for result in results:# 获取边框列表,其中每个边界框由中心点坐标、宽度、高度组成boxes = result.boxes.xywh.tolist()# 逐个绘图im_array = result.plot()for i in range(len(boxes)):  # 遍历boxes列表# 将中心点坐标位置转化为整型,并赋值给ux和uyux, uy = int(boxes[i][0]), int(boxes[i][1])# 得到深度帧中的对应坐标处的距离dis = depth_frame.get_distance(ux, uy)# 将指定深度帧的像素坐标和距离值转化为相机坐标系下的坐标x,y,zcamera_xyz = rs.rs2_deproject_pixel_to_point(depth_intri, (ux, uy), dis)# 将x,y,z转化成3位小数的Numpy数组camera_xyz = np.round(np.array(camera_xyz), 3)# 将单位转化为mmcamera_xyz = camera_xyz * 1000#camera_xyz = np.array(list(camera_xyz)) * 1000# 转化为一个列表camera_xyz = list(camera_xyz)# 在im_array上绘制圆形,圆心坐标为ux,uy,半径为4个像素# 颜色为(255,255,255),线条宽度为5个像素cv2.circle(im_array, (ux, uy), 4, (255, 255, 255), 5)  # 标出中心点# 在im_array上绘制文本框,文本框内容为camera_xyz# 位置为(ux + 20, uy + 10),0字体类型,0.5字体大小,255,255,255字体颜色# 最后两个参数为线宽和线型cv2.putText(im_array, str(camera_xyz), (ux + 20, uy + 10), 0, 0.5,[225, 255, 255], thickness=1, lineType=cv2.LINE_AA)  # 标出坐标# 设置窗口,窗口大小根据图像自动调整cv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)# 将图像images显示在窗口中,这个显示的是带有追踪结果的图像cv2.imshow('RealSense', im_array)key = cv2.waitKey(1)  # 等待用户输入# Press esc or 'q' to close the image windowif key & 0xFF == ord('q') or key == 27:cv2.destroyAllWindows()pipeline.stop()breakfinally:# Stop streamingpipeline.stop()

结果展示:

intel D435i相机实时测量显示物体三维坐标

五、参考学习博文

Realsense D435i 通过YOLOv5、YOLOv8输出目标三维坐标_yolov5+d435i-CSDN博客

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

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

相关文章

常用框架-Dubbo

常用框架-Dubbo 1、Dubbo是什么?2、说说一次Dubbo服务请求流程?3、说说Dubbo 工作原理?4、Dubbo支持哪些通信协议?5、注册中心挂了,consumer还能不能调用provider?6、Dubbo怎么实现动态感知服务下线的呢?7、说说Dubbo负载均衡策略?8、说说Dubbo容错策略?9、说说Dubbo动…

Tomcat多实例配置

目录 一. 复制程序文件 二. 启动tomcat多实例 三. Tomcat多实例负载均衡 多实例(多进程):同一个程序启动多次,分为两种情况: 第一种:一台机器跑多个站点; 第二种:一个机器跑一个站点多个实…

代码随想录训练营第十六天 513找树左下角的值 112路径总和I 113路径总和II 106从中序和后序遍历序列构造二叉树

第一题: 原题链接:513. 找树左下角的值 - 力扣(LeetCode) 思路:用回溯的思想: 这题就是求最大深度,当遍历到第一个最大深度的时候,记录下的节点值就是最左边的元素。 参数和返回…

BFS与DFS

BFS与DFS BFS和DFS 是最简单实现的搜索算法&#xff0c;其他的搜索算法其实都是在他们的基础上发展优化而来的。 力扣模板题 这里要优化一下才可以过这道题 1. BFS BFS 通过 队列来实现 每次都会先遍历当前节点的邻接节点 //这里是用邻接表来表示图 bool bfs(vector<ve…

react学习——13react高阶函数_函数柯里化

1、高阶函数柯里化实现 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><!-- 移动端适配--><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title&g…

提取图像主色调

依赖 Pillow 库。 提取图像主色调&#xff0c;直接上代码&#xff1a; from PIL import Imagedef extract_main_color(img_path: str, delta_h: float 0.3) -> str:"""获取图像主色调Args:img_path: 输入图像的路径delta_h: 像素色相和平均色相做减法的绝…

MIL图像处理那些事:定义感兴趣区域ROI的两种方法(示例项目C#源码)

文章目录 效果展示第一种方法:通过鼠标框选GetROIForm构造函数如何缩放--MdispZoom的使用Ctr+滚轮缩放放大两倍:如何平移--MdispPan的使用双击返回ROI第二种方法:直接编辑ROI框显示ROI示例项目C#源码(百度网盘)本示例提供两种方法定义感兴趣区域ROI 效果展示 第一种方法:通过鼠…

测试基础15:测试用例设计方法-场景设计(流程分析)

课程大纲 1、定义 系统多个功能串联形成业务流程&#xff0c;不仅需要验证正确的主流程&#xff0c;而且需要验证各个功能点各种异常情况。 2、应用场景 与因果图&判定表方法的相似之处&#xff1a;界面需手动填写的输入框少&#xff0c;基本只需选择有限的几个&#xff08…

AppInventor2程序设计里代码块较多,有点卡,有没有办法解决?

问&#xff1a;请问下程序设计里面写的程序比较多&#xff0c;有点卡&#xff0c;这个有没有办法呢&#xff1f; 答&#xff1a;AppInventor2目前不支持代码块的模块化&#xff0c;不过也有一些技巧可以减少代码块的数量&#xff0c;还能提高代码的质量&#xff1a; 1. 提取过程…

小抄 20240620

1 段永平和他的徒弟们经常提的三个词&#xff1a;平常心&#xff0c;本分&#xff0c;常识。 都是很普通的道理&#xff0c;但普通人基本不用。常识&#xff0c;平常人不认识。 2 觉得一件事很大的时候&#xff0c;可以让自己变得更大&#xff0c;来稀释事情的大小。 一个…

Ubuntu系统 常用工具

Ubuntu系统 常用工具 1 输入法 googlepinyin 参考&#xff1a; https://blog.csdn.net/qq_36393978/article/details/118483011 卸载fcitx残留 sudo apt-get remove fcitx sudo apt-get remove fcitx-module* sudo apt-get remove fcitx-frontend* sudo apt-get purge fcit…

Jenkins定时构建自动化(四):Python 的 argparse 模块

目录 一、主要功能和用途 二、核心类和方法 三、总结 四、argparse模块示例 Jenkins定时构建自动化(一)&#xff1a;Jenkins下载安装配置-CSDN博客 Jenkins定时构建自动化(二)&#xff1a;Jenkins的定时构建-CSDN博客 Jenkins定时构建自动化(三)&#xff1a;手动定时构建…

[FreeRTOS 基础知识] 信号量 概念

文章目录 信号量定义信号量特性 信号量定义 信号量是一个抽象的数据类型&#xff0c;通常包含一个整数值以及一个等待该值变为正数的任务列表&#xff08;也称为等待队列&#xff09;。信号量的整数值代表了系统中某种资源的可用数量。 在操作系统中信号量用于控制对共享资源访…

提升办公效率的利器—OnlyOffice文档8.1深度体验

目录 1. 前言 2. 安装 3. 基本使用 3.1 文档编辑 3.2 表格处理 3.3 演示文稿 4. 个人评价 5. 总结 1. 前言 在当今信息化时代&#xff0c;办公软件已经成为我们日常工作中不可或缺的工具。无论是撰写文档、处理数据&#xff0c;还是制作演示文稿&#xff0c;办公软件的…

MySQL MVCC详解

目录 前言 MVCC实现原理 UndoLog版本链 ReadView MVCC是否可以解决不可重复读与幻读 隔离级别 READ UNCOMMITTED - 读未提交与脏读 READ COMMITTED - 读已提交与不可重复读 REPEATABLE READ - 可重复读与幻读 SERIALIZABLE - 串行化 小结 前言 为了提高数据库并发能力…

GNSS接收机的工作原理

GNSS接收机的工作原理如下&#xff1a; 信号接收&#xff1a;GNSS接收机通过天线接收来自卫星导航系统的信号&#xff0c;这些信号包含卫星的位置、时间和健康状态等信息。 信号处理&#xff1a;接收的信号首先经过前置放大器放大&#xff0c;然后经过滤波器滤除噪声。接收机会…

邂逅Three.js探秘图形世界之美

可能了解过three.js等大型的3D 图形库同学都知道啊&#xff0c;学习3D技术都需要有图形学、线性代数、webgl等基础知识&#xff0c;以前读书学的线性代数足够扎实的话听这节课也会更容易理解&#xff0c;这是shader课程&#xff0c;希望能帮助你理解着色器&#xff0c;也面向第…

图象去噪1-使用中值滤波与均值滤波

1、中值滤波 使用中值滤波去除图像的异常像素点&#xff0c;使用cv2.cv2.medianBlur(img, 3)表示再图像在中值滤波窗口3*3的范围内&#xff0c;从下到大排序&#xff0c;将当前值替换为排序中值&#xff08;如下图所示&#xff09;将56替换为&#xff08;56&#xff0c;66,90,…

JeecgFlow并行网关概念及案例演示

概念讲解 并行网关能够在一个流程中用于进行并发建模处理&#xff0c;将单条线路拆分成多条路径并行执行&#xff0c;或者将多条路径合并处理。 在一个流程模型中引入并发最直接的网关就是并行网关&#xff0c;它基于进入和外出顺序流&#xff0c;有分支和合并两种行为&#xf…

Android中使用Scroller实现View的弹性滑动

在 Android 开发中&#xff0c;Scroller 类用于实现 View 的弹性滑动效果。它并不会直接滚动 View&#xff0c;而是用于计算滑动的偏移量&#xff0c;然后应用到 View 上。以下是 Scroller 实现 View 弹性滑动的主要步骤&#xff1a; 1. 初始化 Scroller 首先&#xff0c;在自…