1.介绍
Intel RealSense D435、D455等D4系列:
Intel D4系列深度相机是由英特尔(Intel)公司推出的一款深度感知摄像头,专为实现计算机视觉和深度学习应用而设计。这款相机使用了英特尔的深度感知技术,结合了摄像头和红外(IR)传感器,可以提供高质量的深度图像和 RGB 彩色图像,为开发者提供了丰富的数据源,用于各种应用,包括虚拟现实(VR)、增强现实(AR)、手势识别、人脸识别、姿势识别、3D 扫描等。
以下是Intel D4系列深度相机的一些主要特点和优势:
1. 深度感知技术:
- D4系列相机具备高质量的深度感知功能,能够获取场景中各个物体的精确距离信息,而不仅仅是RGB图像。
2. 多模式操作:
- 相机支持多种操作模式,包括手势识别、人脸识别、物体追踪等。这使得它非常适合于需要人机交互的应用领域。
3. 低光环境适应:
- D4系列深度相机在低光环境下也能够提供准确的深度信息,这使得它在各种不同的环境中都能够稳定工作。
4. 易于集成:
- 相机提供了丰富的软件开发工具,开发者可以方便地将其集成到自己的应用中,快速开发深度感知应用。
5. 多平台支持:
- D4系列深度相机支持多种操作系统,包括Windows、Linux等,也提供了各种开发语言的API,方便开发者在不同平台上使用。
6. 精准度和稳定性:
- 相机具有高精度和稳定性,能够在不同距离范围内提供准确的深度信息,这对于需要精确度的应用非常重要。
结构光(Structured-light)
基本原理是,通过近红外激光器,将具有一定结构特征的光线投射到被拍摄物体上,再由专门的红外摄像头进行采集。这种具备一定结构的光线,会因被摄物体的不同深度区域,而采集不同的图像相位信息,然后通过运算单元将这种结构的变化换算成深度信息,以此来获得三维结构。通常采用特定波长的不可见的红外激光作为光源,它发射出来的光经过一定的编码投影在物体上,通过一定算法来计算返回的编码图案的畸变来得到物体的位置和深度信息。
结构光的优点主要有:
1)方案成熟,相机基线可以做的比较小,方便小型化。
2)资源消耗较低,单帧 IR 图就可计算出深度图,功耗低。
3)主动光源,夜晚也可使用。
4)在一定范围内精度高,分辨率高,分辨率可达 1280x1024,帧率可达 60FPS。
结构光的缺点:
1)容易受环境光干扰,室外体验差。
2)随检测距离增加,精度会变差。
2.初识深度相机
import pyrealsense2 as rs
import numpy as np
import cv2# Configure depth and color streams
pipeline = rs.pipeline()
config = rs.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)config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)# Start streaming
pipeline.start(config)try:while True:# Wait for a coherent pair of frames: depth and colorframes = 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 arraysdepth_image = np.asanyarray(depth_frame.get_data())color_image = np.asanyarray(color_frame.get_data())# print(f"depth_image shape: {depth_image.shape} color_image shape: {color_image.shape}")print(f"depth_image value: {depth_image}") # 里面0值很多,还有很多1900左右的值 300mm 单位是毫米=30厘米=0.3米# depth_image shape: (480, 640) color_image shape: (480, 640, 3)# 深度图是单通道 颜色图是三通道的# Apply colormap on depth image (image must be converted to 8-bit per pixel first)# 在深度图像上应用colormap(图像必须先转换为每像素8位)depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.03), cv2.COLORMAP_JET)# Stack both images horizontallyimages = np.hstack((color_image, depth_colormap))# Show imagescv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)cv2.imshow('RealSense', images)key = cv2.waitKey(1)if key & 0xFF == ord('q') or key == 27:cv2.destroyAllWindows()breakfinally:# Stop streamingpipeline.stop()
3.代码详解
pipeline = rs.pipeline()
config = rs.config()
rs.pipeline()
和rs.config()
是pyrealsense2
库中的两个函数,用于创建一个深度摄像机数据流的通道(pipeline)和一个配置对象(config)。
rs.pipeline()
函数返回一个管道对象,该对象可以用于操作由Intel RealSense深度相机生成的数据流。它允许您将相机的输入流(例如,颜色、深度或红外图像)与其他Python代码连接起来。在使用RealSense相机前,需要先创建一个管道对象。创建方式为:
pipeline = rs.pipeline()
rs.config()
函数返回一个配置对象,用于配置深度相机中的参数。您可以使用配置对象设置数字和字母参数,例如相机分辨率、帧速率、输出格式等。在创建管道后,需要创建一个配置对象,以便为您的管道指定任何必需的属性。创建方式为:config = rs.config()
要启用深度和颜色流,可以使用
config.enable_stream()
方法,在实例化配置对象之后调用。config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30) config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
这里,我们启用了分辨率为640x480、帧速率为30fps的深度流和彩色流,并指定了它们的格式(
rs.format.z16
和rs.format.bgr8
)。
pipeline.start(config)
pipeline.start(config)
是用于开始深度相机数据流的函数调用。在实例化管道对象和配置对象之后,需要调用start()
方法来启动数据流。具体来说,
start()
方法会将配置对象传递给管道对象,并开始捕获深度相机生成的数据。这样,您就可以从相机读取帧并对其进行处理。pipeline.start(config)
这将根据提供的配置开始从深度相机读取数据帧。一旦启动数据流,您就可以使用
wait_for_frames()
方法等待并获取一对同步的深度帧和颜色帧进行后续处理。请确保在调用
start()
方法之前已经正确配置了管道和配置对象。同时,确保在不再需要数据流时调用pipeline.stop()
来停止数据流的捕获和处理。
frames = pipeline.wait_for_frames()# 深度图depth_frame = frames.get_depth_frame()# 正常读取的视频流color_frame = frames.get_color_frame()
frames = pipeline.wait_for_frames()
等待并获取一对同步的深度帧和彩色帧,
wait_for_frames()
方法在这里起到阻塞的作用,直到有新的数据帧可用才会继续执行。depth_frame = frames.get_depth_frame()
从
frames
中获取深度帧,深度帧包含了相机捕获的深度信息。color_frame = frames.get_color_frame()
从
frames
中获取彩色帧,彩色帧包含了相机捕获的彩色图像信息。通过以上几行代码,您可以同时获取深度图和彩色帧,以进一步进行后续处理。请注意,在调用
get_depth_frame()
和get_color_frame()
之前,要确保已经调用了wait_for_frames()
来获取最新的一对数据帧。如果没有获取到有效的深度帧或彩色帧,返回的值将为
None
。因此,建议在使用这些帧之前进行有效性检查,以避免出现错误。
if not depth_frame or not color_frame:continue
这是一个简单的错误检查,用于确保从深度相机中获取了有效的深度帧和彩色帧。如果depth_frame
或color_frame
中的任意一个为None
,则会跳过当前循环,并等待下一次数据帧。这可以避免在没有有效数据的情况下继续执行一些后续操作,导致程序出错。
depth_image = np.asanyarray(depth_frame.get_data())color_image = np.asanyarray(color_frame.get_data())
这段代码用于将深度帧和彩色帧转换为
numpy
数组,以便进一步进行处理。depth_image = np.asanyarray(depth_frame.get_data())
将深度帧转换为
numpy
数组形式。depth_frame.get_data()
方法将深度帧中的像素数据返回为一个字节串(byte string),然后通过np.asanyarray()
函数将其转换为numpy
数组格式。color_image = np.asanyarray(color_frame.get_data())
将彩色帧转换为
numpy
数组形式。color_frame.get_data()
方法将彩色帧中的像素数据返回为一个字节串(byte string),然后通过np.asanyarray()
函数将其转换为numpy
数组格式。一旦您将深度帧和彩色帧转换为
numpy
数组,就可以使用numpy
库中的各种函数来对这些帧进行处理。例如,您可以使用numpy
库中的矩阵操作函数来对深度图像进行处理,或者使用matplotlib
库中的函数来显示彩色帧。请注意,
asanyarray()
函数对任何输入都将返回数组视图(即指向原始数据的指针),除非无法安全地返回此类视图,否则不会进行复制。
# print(f"depth_image shape: {depth_image.shape} color_image shape: {color_image.shape}")print(f"depth_image value: {depth_image}") # 里面0值很多,还有很多1900左右的值 300mm 单位是毫米=30厘米=0.3米# depth_image shape: (480, 640) color_image shape: (480, 640, 3)# 深度图是单通道 颜色图是三通道的
用于打印出深度图和彩色帧的一些基本信息,以便确认获取的数据是否正确。
print(f"depth_image shape: {depth_image.shape} color_image shape: {color_image.shape}")
打印出深度图和彩色帧的形状,即它们各自包含多少行和列。在这个例子中,深度图是单通道的,形状为
(480, 640)
,而彩色帧则是三通道的,形状为(480, 640, 3)
。print(f"depth_image value: {depth_image}")
打印出深度图像素值的数组,以便查看深度图中不同位置的像素值。深度图的像素值表示距离相机的距离,单位为毫米(mm)。因此,0代表相机无法检测到物体,而更大的值代表物体离相机越远。在打印的结果中,您可以看到很多0值和一些接近1900左右的值,这可能表示相机检测不到这些物体或者这些物体距离比较远。
# Apply colormap on depth image (image must be converted to 8-bit per pixel first)# 在深度图像上应用colormap(图像必须先转换为每像素8位)depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.03), cv2.COLORMAP_JET)
在深度图像上应用色彩映射,使深度信息可视化。
depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.03), cv2.COLORMAP_JET)
cv2.convertScaleAbs()
函数用于将深度图像转换为8位图像。它通过将深度图像的像素值缩放到指定范围内,并取绝对值来确保结果是非负整数,然后将浮点型数据转换为8位无符号整数数据。cv2.applyColorMap()
函数用于将8位深度图像应用颜色映射。cv2.COLORMAP_JET
参数指定了使用的颜色映射方案,其中JET
表示将深度值映射到一种彩虹色的颜色表示。不同深度值将映射到不同的颜色。最终,
depth_colormap
变量将包含应用颜色映射后的深度图像。这样,您就可以通过可视化的方式观察深度信息,不同深度值将以不同的颜色显示出来。