realsense-rust 1.3.0

High-level RealSense library in Rust
Documentation
//! This example demonstrates the decimation filter processing block with Rerun visualization
//! It opens a depth stream, applies decimation to reduce resolution, and visualizes both original and decimated results

use anyhow::{ensure, Result};
use realsense_rust::{
    config::Config,
    context::Context,
    frame::{DepthFrame, PixelKind},
    kind::{Rs2Format, Rs2StreamKind},
    pipeline::InactivePipeline,
    processing_blocks::{colorizer::Colorizer, decimation::Decimation},
};
use rerun::{self as rr, external::image};
use std::{collections::HashSet, convert::TryFrom, time::Duration};

fn main() -> Result<()> {
    // Initialize Rerun
    let rec = rr::RecordingStreamBuilder::new("realsense_decimation").spawn()?;

    // Create RealSense context and check for available devices
    let context = Context::new()?;
    let devices = context.query_devices(HashSet::new());
    ensure!(!devices.is_empty(), "No devices found");

    println!("Found {} device(s), using the first one", devices.len());

    // Create pipeline and configuration
    let pipeline = InactivePipeline::try_from(&context)?;
    let mut config = Config::new();
    config.enable_stream(Rs2StreamKind::Depth, Some(0), 640, 480, Rs2Format::Z16, 30)?;

    // Start pipeline
    let mut active_pipeline = pipeline.start(Some(config))?;

    // Create processing blocks
    let mut decimation = Decimation::new(5)?;
    let mut colorizer_decimated = Colorizer::new(5)?;

    println!("Starting decimation filter with Rerun visualization.");
    println!("Showing original vs decimated depth data.");
    println!("Press Ctrl+C to quit.");

    let mut frame_count = 0;

    loop {
        let frames = active_pipeline.wait(Some(Duration::from_millis(1000)))?;

        // Get depth frame
        let depth_frames: Vec<DepthFrame> = frames.frames_of_type();
        if let Some(depth_frame) = depth_frames.into_iter().next() {
            frame_count += 1;

            // Store original dimensions and log raw depth data every 30th frame
            let original_width = depth_frame.width() as u32;
            let original_height = depth_frame.height() as u32;

            let depth_data: Vec<u16> = depth_frame
                .iter()
                .map(|pixel| match pixel {
                    PixelKind::Z16 { depth } => *depth,
                    _ => 0,
                })
                .collect();

            let depth_image: image::ImageBuffer<image::Luma<u16>, Vec<u16>> =
                image::ImageBuffer::from_raw(original_width, original_height, depth_data).unwrap();

            rec.log(
                "depth/raw_original",
                &rr::DepthImage::try_from(depth_image)?,
            )?;

            // Apply decimation filter
            decimation.queue(depth_frame)?;

            // Wait for decimated frame
            match decimation.wait(Duration::from_millis(100)) {
                Ok(decimated_frame) => {
                    let dec_width = decimated_frame.width() as u32;
                    let dec_height = decimated_frame.height() as u32;

                    // Log raw decimated depth data every 30th frame
                    if frame_count % 30 == 0 {
                        let decimated_depth_data: Vec<u16> = decimated_frame
                            .iter()
                            .map(|pixel| match pixel {
                                PixelKind::Z16 { depth } => *depth,
                                _ => 0,
                            })
                            .collect();

                        let decimated_depth_image: image::ImageBuffer<image::Luma<u16>, Vec<u16>> =
                            image::ImageBuffer::from_raw(
                                dec_width,
                                dec_height,
                                decimated_depth_data,
                            )
                            .unwrap();

                        rec.log(
                            "depth/raw_decimated",
                            &rr::DepthImage::try_from(decimated_depth_image)?,
                        )?;
                    }

                    // Apply colorizer to decimated frame
                    colorizer_decimated.queue(decimated_frame)?;

                    match colorizer_decimated.wait(Duration::from_millis(100)) {
                        Ok(colorized_frame) => {
                            // Convert colorized frame to RGB data for Rerun
                            let mut rgb_data = Vec::new();

                            for pixel in colorized_frame.iter() {
                                match pixel {
                                    PixelKind::Bgr8 { b, g, r } => {
                                        rgb_data.extend_from_slice(&[*r, *g, *b]);
                                    }
                                    PixelKind::Rgb8 { r, g, b } => {
                                        rgb_data.extend_from_slice(&[*r, *g, *b]);
                                    }
                                    _ => {
                                        // Fallback for other formats
                                        rgb_data.extend_from_slice(&[0, 0, 0]);
                                    }
                                }
                            }

                            // Create Rerun image from RGB data
                            let width = colorized_frame.width() as u32;
                            let height = colorized_frame.height() as u32;

                            rec.log(
                                "depth/decimated_colorized",
                                &rr::Image::from_rgb24(rgb_data, [width, height]),
                            )?;

                            if frame_count % 60 == 0 {
                                println!(
                                    "Processed {} frames - Original: {}x{}, Decimated: {}x{}",
                                    frame_count, original_width, original_height, width, height
                                );
                            }
                        }
                        Err(e) => {
                            eprintln!("Error processing colorized decimated frame: {}", e);
                        }
                    }
                }
                Err(e) => {
                    eprintln!("Error applying decimation filter: {}", e);
                }
            }
        }
    }
}