欢迎光临
我们一直在努力

在Windows11系统上配置interl Realsense D435i深度相机+Python

一、产品介绍

Intel RealSense D435i是英特尔公司推出的一款消费级深度相机,它的主要构成如下图所示。

主要包含一个RGB相机、两个红外相机以及一个红外发射器,此外还有一个IMU单元(这也就是D435i和D435的区别,i就表示imu)。简单来说它的深度成像原理是主动立体红外成像,不是传统意义上理解的双目RGB相机成像,这点需要注意一下。 有了深度图(3D点云)和对应的RGB影像,因此也就很容易获得RGB-D点云了。因此从输出的角度而言,D435i可以看做是一个RGB-D传感器相机。后续可以搭配ORB-SLAM中RGB-D的模式进行使用。当然,也可以只用单目RGB影像,以单目SLAM模式运行,或者单目结合IMU,以Mono-Initial模式运行。唯一不能运行的是双目RGB模式(因为两个红外相机是单通道的)。当然我们可以获取双目的红外影像,以此作为输入,进行双目SLAM,结果也是类似的。因此可以看出,D435i是一个比较“全能”的传感器,从单目、单目+IMU、双目、双目+IMU、RGB-D都可以使用。

对于它的一些技术上的参数,这里也简单列举一下:

  • 深度技术:主动立体IR
  • 图像传感器技术:3μm×3μm像素大小,全局快门
  • 深度视场(H×V):86°×57°(±3°)
  • 深度分辨率&帧率:1280×720,90FPS(最高)
  • RGB传感器技术:卷帘快门
  • RGB传感器分辨率&帧率:1920×1080,30FPS(最高)
  • RGB传感器FOV(H×V):69°×42°(±1°)
  • 最小深度距离(Min-Z):0.105m
  • 最大范围:约10m
  • 尺寸(长宽高):90mm × 25mm × 25mm

从上面的参数中,也可以看出来它的一些特点。比如深度图和RGB影像的大小是不同的,换句话说RGB影像中只有和深度图重叠的那部分才有深度信息,否则是没有的。同时帧率也不相同,如果需要使用RGB-D信息,那么时间同步也可能是个需要处理的问题。第二点是RGB传感器采用的是卷帘快门,因此在一些高速运动的场景下,可能会出现果冻效应。最后由于采用主动红外测距技术,而红外传感器本身发射的信号强度有限,最大10m左右,因此并不能适用于室外很大的场景。

二、SDK下载

2.1 下载

进入网址:RealSense SDK 2.0 直接拉到网站最下端,在Asset下可以看到很多exe可执行软件,由于我的电脑是win11,所以选择第三个。

注:win11和win10的SDK通用的,均可使用。

装SDK会附带安装可视化界面Viewer、Examples和Depth Quality Tool。

2.2 安装与测试

首先,连接D435i到电脑上,然后在终端中输入<font style="color:rgb(199, 37, 78);background-color:rgb(249, 242, 244);">realsense-viewer</font>启动数据可视化界面,如下图所示。

点击左侧的Stereo Module可以开启深度图显示,RGB Module可以显示RGB影像,Motion Module会显示IMU相关数据,如下图所示。

如果可以正常显示上图中的画面,那么就说明RealSense的基本配置就成功了,可以向电脑传输数据了。

同样地,Stereo Module和RGB Camera可以分别设置参数(很重要,后面要用到)。这里简单说一下,Stereo Module的作用是用来设置深度信息的,而RGB Camera就是用来设置RGB颜色信息的!当然,主要用到的还是分辨率和FPS。

三、结合python配置相机

3.1 虚拟环境配置

  • 首先在windows下安装anaconda和Vscode,然后配置open3d新环境。
  • 创建一个新的环境,以下分别是python 版本是3.8和3.6的安装教程。
  • 在conda终端下使用命令:
  • #创建python3.6环境
    conda create n Rd543i python=3.6

    #激活使用python3.6
    conda activate Rd543i

    #创建python3.8环境
    conda create n Rd543i python=3.8

    #激活使用python3.8
    conda activate Rd543i

  • 配置opencv环境,安装opencv。
  • ## python3.6的版本必须装这个版本,此处必须按照指定版本安装
    pip install i https://mirrors.aliyun.com/pypi/simple/ opencvpython==4.3.0.38
    pip install opencvcontribpython==4.4.0.46

    pip install opencvpython
    pip install opencvcontribpython

  • 接着安装open3d和pyrealsense2,open3d需要等很长时间。
  • pip install pywinpty==1.1.4
    pip install open3d==0.15.1
    pip install pyrealsense2==2.48.0.3891

    pip install open3d
    pip install pyrealsense2

    3.2 可视化

    可视化脚本:

    import pyrealsense2 as rs
    import numpy as np
    import cv2

    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, 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 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())

    # 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()

    运行脚本结果如下图所示:

    四、结合python+Vscode实现数据采集

    4.1 实现RGB数据采集

    脚本:

    import os
    import cv2
    import numpy as np
    import pyrealsense2 as rs
    import time

    # 初始化 RealSense
    pipeline = rs.pipeline()
    config = rs.config()
    config.enable_stream(rs.stream.color, 1920, 1080, rs.format.bgr8, 15)
    profile = pipeline.start(config)

    cv2.namedWindow('RGB Image', cv2.WINDOW_AUTOSIZE)

    # 设置保存目录
    save_dir = 'E:/my_images/'
    os.makedirs(save_dir, exist_ok=True)

    counter = 0

    try:
    while True:
    frames = pipeline.wait_for_frames()
    color_frame = frames.get_color_frame()
    if not color_frame:
    continue

    # 获取 RGB 图像数据
    color_image = np.asanyarray(color_frame.get_data())
    cv2.imshow('RGB Image', color_image)

    # 按 't' 键保存 RGB 图像
    key = cv2.waitKey(1)
    if key == ord('t'):
    rgb_file = os.path.join(save_dir, f'rgb_{counter:04d}.png')
    cv2.imwrite(rgb_file, color_image)
    print(f'Saved: {rgb_file}')
    counter += 1

    # 按 'q' 或 ESC 退出
    if key in [27, ord('q')]:
    cv2.destroyAllWindows()
    break
    finally:
    pipeline.stop()

    五、一些其他扩展玩法

    5.1 YOLOv8结合相机

    具体脚本如下:

    import cv2
    import pyrealsense2 as rs
    import time
    import numpy as np
    import math
    from ultralytics import YOLO

    # 加载 YOLOv8 模型
    model = YOLO("runs/detect/train/weights/best.pt")

    # # 获取摄像头内容,参数 0 表示使用默认的摄像头
    # cap = cv2.VideoCapture(1)

    # 配置 RealSense
    pipeline = rs.pipeline()
    config = rs.config()
    config.enable_stream(rs.stream.depth, 848, 480, rs.format.z16, 30)
    config.enable_stream(rs.stream.color, 848, 480, rs.format.bgr8, 30)

    # 启动相机流
    pipeline.start(config)
    align_to = rs.stream.color # 与color流对齐
    align = rs.align(align_to)

    def get_aligned_images():
    frames = pipeline.wait_for_frames() # 等待获取图像帧
    aligned_frames = align.process(frames) # 获取对齐帧
    aligned_depth_frame = aligned_frames.get_depth_frame() # 获取对齐帧中的depth帧
    color_frame = aligned_frames.get_color_frame() # 获取对齐帧中的color帧

    # 相机参数的获取
    intr = color_frame.profile.as_video_stream_profile().intrinsics # 获取相机内参
    depth_intrin = aligned_depth_frame.profile.as_video_stream_profile(
    ).intrinsics # 获取深度参数(像素坐标系转相机坐标系会用到)
    '''camera_parameters = {'fx': intr.fx, 'fy': intr.fy,
    'ppx': intr.ppx, 'ppy': intr.ppy,
    'height': intr.height, 'width': intr.width,
    'depth_scale': profile.get_device().first_depth_sensor().get_depth_scale()
    }'''

    # 保存内参到本地
    # with open('./intrinsics.json', 'w') as fp:
    # json.dump(camera_parameters, fp)
    #######################################################

    depth_image = np.asanyarray(aligned_depth_frame.get_data()) # 深度图(默认16位)
    depth_image_8bit = cv2.convertScaleAbs(depth_image, alpha=0.03) # 深度图(8位)
    depth_image_3d = np.dstack(
    (depth_image_8bit, depth_image_8bit, depth_image_8bit)) # 3通道深度图
    color_image = np.asanyarray(color_frame.get_data()) # RGB图

    # 返回相机内参、深度参数、彩色图、深度图、齐帧中的depth帧
    return intr, depth_intrin, color_image, depth_image, aligned_depth_frame

    def get_3d_camera_coordinate(depth_pixel, aligned_depth_frame, depth_intrin):
    x = depth_pixel[0]
    y = depth_pixel[1]
    dis = aligned_depth_frame.get_distance(x, y) # 获取该像素点对应的深度
    # print ('depth: ',dis) # 深度单位是m
    camera_coordinate = rs.rs2_deproject_pixel_to_point(depth_intrin, depth_pixel, dis)
    # print ('camera_coordinate: ',camera_coordinate)
    return dis, camera_coordinate

    # 初始化 FPS 计算
    fps = 0
    frame_count = 0
    start_time = time.time()

    try:
    while True:
    # 等待获取一对连续的帧:深度和颜色
    intr, depth_intrin, color_image, depth_image, aligned_depth_frame = get_aligned_images()

    if not depth_image.any() or not color_image.any():
    continue

    # 获取当前时间
    time1 = time.time()

    # 将图像转为numpy数组
    depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(
    depth_image, alpha=0.03), cv2.COLORMAP_JET)
    images = np.hstack((color_image, depth_colormap))

    # 使用 YOLOv8 进行目标检测
    results = model.predict(color_image, conf=0.5)
    annotated_frame = results[0].plot()
    detected_boxes = results[0].boxes.xyxy # 获取边界框坐标
    # print('方框坐标', detected_boxes)
    for i, box in enumerate(detected_boxes):
    x1, y1, x2, y2 = map(int, box) # 获取边界框坐标

    # 计算步长
    xrange = max(1, math.ceil(abs((x1 x2) / 30)))
    yrange = max(1, math.ceil(abs((y1 y2) / 30)))
    # xrange = 1
    # yrange = 1

    point_cloud_data = []

    # 获取范围内点的三维坐标
    for x_position in range(x1, x2, xrange):
    for y_position in range(y1, y2, yrange):
    depth_pixel = [x_position, y_position]
    dis, camera_coordinate = get_3d_camera_coordinate(depth_pixel, aligned_depth_frame,
    depth_intrin) # 获取对应像素点的三维坐标
    point_cloud_data.append(f"{camera_coordinate} ")

    # 一次性写入所有数据
    with open("point_cloud_data.txt", "a") as file:
    file.write(f"\\nTime: {time.time()}\\n")
    file.write(" ".join(point_cloud_data))

    # 显示中心点坐标
    ux = int((x1 + x2) / 2)
    uy = int((y1 + y2) / 2)
    dis, camera_coordinate = get_3d_camera_coordinate([ux, uy], aligned_depth_frame,
    depth_intrin) # 获取对应像素点的三维坐标
    formatted_camera_coordinate = f"({camera_coordinate[0]:.2f}, {camera_coordinate[1]:.2f}, {camera_coordinate[2]:.2f})"

    cv2.circle(annotated_frame, (ux, uy), 4, (255, 255, 255), 5) # 标出中心点
    cv2.putText(annotated_frame, formatted_camera_coordinate, (ux + 20, uy + 10), 0, 1,
    [225, 255, 255], thickness=1, lineType=cv2.LINE_AA) # 标出坐标

    # 计算 FPS
    frame_count += 1
    time2 = time.time()
    fps = int(1 / (time2 time1))
    # 显示 FPS
    cv2.putText(annotated_frame, f'FPS: {fps:.2f}', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2,
    cv2.LINE_AA)
    # 显示结果
    cv2.imshow('YOLOv8 RealSense', annotated_frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
    break

    finally:
    # 停止流
    pipeline.stop()

    5.2 关键点识别结合相机

    脚本思路:

    1、获取相机对齐图像帧与相机参数

    frames = pipeline.wait_for_frames() # 等待获取图像帧,获取颜色和深度的框架集
    aligned_frames = align.process(frames) # 获取对齐帧,将深度框与颜色框对齐

    aligned_depth_frame = aligned_frames.get_depth_frame() # 获取对齐帧中的的depth帧
    aligned_color_frame = aligned_frames.get_color_frame() # 获取对齐帧中的的color帧

    #### 获取相机参数 ####
    depth_intrin = aligned_depth_frame.profile.as_video_stream_profile().intrinsics # 获取深度参数(像素坐标系转相机坐标系会用到)
    color_intrin = aligned_color_frame.profile.as_video_stream_profile().intrinsics # 获取相机内参

    #### 将images转为numpy arrays ####
    img_color = np.asanyarray(aligned_color_frame.get_data()) # RGB图
    img_depth = np.asanyarray(aligned_depth_frame.get_data()) # 深度图(默认16位)

    2、检测

    # 检测
    result = list(model(image, conf=0.3, stream=True))[0] # inference
    boxes = result.boxes # Boxes object for bbox outputs
    boxes = boxes.cpu().numpy() # convert to numpy array

    3、遍历所有的Keypoints

    # 遍历keypoints
    keypoints = result.keypoints # Keypoints object for pose outputs
    keypoints = keypoints.cpu().numpy() # convert to numpy array

    4、获得所有关键点二维坐标

    point1 = (int(x0), int(y0))
    point2 = (int(x1), int(y1))

    5、计算所有点的深度值

    point1_dis = depth_frame.get_distance(x0, y0) # 获取第一个点的深度值
    point2_dis = depth_frame.get_distance(x1, y1) # 获取第二个点的深度值

    6、计算所有点的三维坐标

    point1_dis = depth_frame.get_distance(x0, y0) # 获取第一个点的深度值
    point2_dis = depth_frame.get_distance(x1, y1) # 获取第二个点的深度值

    赞(0)
    未经允许不得转载:171主机测评 » 在Windows11系统上配置interl Realsense D435i深度相机+Python
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址