You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Intel RealSense D435生成点云并绘制Matplotlib 3D散点图

Hey there! Let's break this down step by step since you're working with such a cool setup (D435 + Raspberry Pi RC car + ArUco localization) and just need that push to get the point cloud part working. I'll walk you through fixing the get_3dPoints function, plus show you a full working snippet that pulls data from the D435 and renders it with Matplotlib's 3D scatter plot.

First, Setup Dependencies

First, make sure you have the right libraries installed on your Raspberry Pi—these are all beginner-friendly and well-supported:

  • pyrealsense2: Intel's official library for interacting with RealSense cameras
  • matplotlib: For creating the 3D scatter plots
  • numpy: To handle the point cloud data arrays

Install them with this command in your terminal:

pip install pyrealsense2 matplotlib numpy

Full Code with Improved get_3dPoints

Here's a complete, commented script that connects to your D435, pulls the point cloud, cleans up invalid data, and renders a clean, untextured 3D scatter plot. The get_3dPoints function is built specifically to extract usable coordinates from the camera's output:

import pyrealsense2 as rs
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def get_3dPoints(points):
    """
    Extract valid 3D coordinates from RealSense point cloud data
    Args:
        points: rs.points object from the RealSense camera pipeline
    Returns:
        Numpy arrays of x, y, z coordinates (only points with valid depth data)
    """
    # Convert the RealSense point cloud object to a numpy array
    # Shape will be (height, width, 3) where each cell holds [x, y, z] values
    point_cloud = np.asanyarray(points.get_data())
    
    # Reshape the 2D grid into a flat list of all points (total_points, 3)
    flattened_points = point_cloud.reshape(-1, 3)
    
    # Filter out invalid points: D435 returns z=0 for areas it can't detect
    # Adjust the z-range based on your indoor space (e.g., 0.1 to 3 meters)
    valid_points = flattened_points[(flattened_points[:, 2] > 0.1) & (flattened_points[:, 2] < 3.0)]
    
    # Split the valid points into separate x, y, z arrays for plotting
    x = valid_points[:, 0]
    y = valid_points[:, 1]
    z = valid_points[:, 2]
    
    return x, y, z

def main():
    # Initialize the RealSense pipeline and config
    pipeline = rs.pipeline()
    config = rs.config()
    
    # Enable depth and color streams (adjust resolution/fps for Pi performance)
    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 from the camera
    pipeline.start(config)
    
    try:
        # Wait for a full frame set (depth + 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:
            print("Failed to capture frames from the D435")
            return
        
        # Process the depth frame into a point cloud
        pc = rs.pointcloud()
        pc.map_to(color_frame)  # Align point cloud with color data (optional but helpful)
        points = pc.calculate(depth_frame)
        
        # Extract valid 3D points using our function
        x, y, z = get_3dPoints(points)
        
        # Create the 3D scatter plot (untextured, just plain points)
        fig = plt.figure(figsize=(10, 8))
        ax = fig.add_subplot(111, projection='3d')
        
        # Plot points with a simple gray color to keep it untextured
        ax.scatter(x, y, z, c='gray', s=1)
        
        # Label axes (matches the D435's coordinate system: X=right, Y=down, Z=forward)
        ax.set_xlabel('X (meters)')
        ax.set_ylabel('Y (meters)')
        ax.set_zlabel('Z (meters)')
        
        # Adjust the view to match your indoor setup
        ax.set_title('D435 Indoor Point Cloud (Valid Points Only)')
        ax.view_init(elev=30, azim=-45)
        
        plt.show()
        
    finally:
        # Always stop the pipeline when done to avoid camera lockup
        pipeline.stop()

if __name__ == "__main__":
    main()

Key Details in get_3dPoints

I added comments to the code, but let's highlight the most important parts for your understanding:

  • Convert to Numpy Array: The RealSense rs.points object isn't directly usable for plotting, so we convert it to a numpy array to easily manipulate the data.
  • Filter Invalid Points: The D435 returns z=0 for areas it can't detect (like too close or too far). Filtering these out ensures your plot only shows real obstacles and surfaces.
  • Split Coordinates: Matplotlib's scatter function expects separate x/y/z arrays, so we split the valid points into three distinct arrays for plotting.

Quick Raspberry Pi Performance Tip

If the script runs slow on your Pi, try dropping the camera resolution to 320x240 in the config.enable_stream lines. This reduces the amount of data the Pi has to process, which makes the point cloud rendering smoother.

Next Steps for A* Path Planning

Once you can reliably get the point cloud, here's a quick roadmap for integrating A*:

  1. Convert the 3D point cloud into a 2D occupancy grid (since your RC car moves on a flat surface, you can ignore the Z-axis or use it to filter out ground points).
  2. Feed this occupancy grid into your A* algorithm to generate a collision-free path from point A to B.
  3. Hook the planned path into your existing ArUco localization script to control the car's movement.

内容的提问来源于stack exchange,提问作者Samm Flynn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:33:52