mod utils;
use std::time::Duration;
use orbbec_sdk::{
Context, Format, HoleFillMode, PermissionType, SensorType,
device::DeviceProperty,
filter::{
DecimationFilter, Filter, HoleFillingFilter, SpatialModerateFilter, TemporalFilter,
ThresholdFilter,
},
pipeline::{Config, Pipeline},
};
use show_image::{ImageInfo, ImageView, WindowOptions, create_window, run_context};
const DEPTH_WIDTH: u16 = 848;
const DEPTH_HEIGHT: u16 = 480;
const FPS: u8 = 15;
fn main() {
run_context(user_task);
}
fn user_task() {
let context = Context::new().unwrap();
let devices = context.query_device_list().unwrap();
if devices.is_empty() {
eprintln!("No Orbbec devices found.");
return;
}
let mut device = devices.get(0).unwrap();
device.load_preset("High Accuracy").unwrap();
let hw_noise = DeviceProperty::HWNoiseRemoveFilterEnable(true);
if device
.is_property_supported(hw_noise, PermissionType::Write)
.unwrap()
{
device.set_property(hw_noise).unwrap();
device
.set_property(DeviceProperty::HWNoiseRemoveFilterThreshold(0.2))
.unwrap();
device
.set_property(DeviceProperty::DepthNoiseRemovalFilter(false))
.unwrap();
println!("Using HW depth noise filter.");
} else {
device
.set_property(DeviceProperty::DepthNoiseRemovalFilter(true))
.unwrap();
device
.set_property(DeviceProperty::DepthNoiseRemovalFilterMaxDiff(256))
.unwrap();
device
.set_property(DeviceProperty::DepthNoiseRemovalFilterMaxSpeckleSize(80))
.unwrap();
println!("Using SW depth noise filter.");
}
let mut config = Config::new().unwrap();
let mut pipeline = Pipeline::new(&device).unwrap();
let depth_profiles = pipeline.get_stream_profiles(SensorType::Depth).unwrap();
let depth_profile = depth_profiles
.get_video_stream_profile(DEPTH_WIDTH, DEPTH_HEIGHT, Format::Y16, FPS)
.unwrap();
config.enable_stream_with_profile(&depth_profile).unwrap();
let mut decimation_filter: DecimationFilter = DecimationFilter::new().unwrap();
decimation_filter.set_factor(2).unwrap();
let mut spatial_filter = SpatialModerateFilter::new().unwrap();
spatial_filter.set_threshold(160).unwrap();
spatial_filter.set_magnitude(3).unwrap();
spatial_filter.set_radius(5).unwrap();
let mut temporal_filter = TemporalFilter::new().unwrap();
temporal_filter.set_threshold(0.1).unwrap();
temporal_filter.set_weight(0.4).unwrap();
let mut hole_filling_filter = HoleFillingFilter::new().unwrap();
hole_filling_filter
.set_mode(HoleFillMode::Farthest)
.unwrap();
let mut threshold_filter = ThresholdFilter::new().unwrap();
threshold_filter.set_min_depth(200).unwrap();
threshold_filter.set_max_depth(4000).unwrap();
pipeline.start(&config).unwrap();
let window_config = WindowOptions {
preserve_aspect_ratio: true,
default_controls: false,
..Default::default()
};
let orig_window = create_window("Original Depth", window_config.clone())
.expect("Failed to create original depth window");
let filter_window = create_window("Filtered Depth", window_config.clone())
.expect("Failed to create filtered depth window");
loop {
let frameset = match pipeline
.wait_for_frames(Duration::from_millis(100))
.unwrap()
{
Some(frameset) => frameset,
None => {
eprintln!("Timeout waiting for frames.");
continue;
}
};
let depth_frame = frameset.get_depth_frame().unwrap().unwrap();
let orig_depth_res = (depth_frame.width(), depth_frame.height());
let orig_depth_data = depth_frame.raw_data();
let depth_frame = decimation_filter.process(&depth_frame).unwrap();
let depth_frame = spatial_filter.process(&depth_frame).unwrap();
let depth_frame = temporal_filter.process(&depth_frame).unwrap();
let depth_frame = hole_filling_filter.process(&depth_frame).unwrap();
let depth_frame = threshold_filter.process(&depth_frame).unwrap();
let filtered_depth_res = (depth_frame.width(), depth_frame.height());
let depth_filtered_data = depth_frame.raw_data();
let orig_depth_image = utils::depth2image(orig_depth_data).unwrap();
let depth_image = utils::depth2image(depth_filtered_data).unwrap();
let orig_image = ImageView::new(
ImageInfo::rgb8(orig_depth_res.0 as u32, orig_depth_res.1 as u32),
&orig_depth_image,
);
orig_window.set_image("Original Depth", orig_image).unwrap();
let depth_image = ImageView::new(
ImageInfo::rgb8(filtered_depth_res.0 as u32, filtered_depth_res.1 as u32),
&depth_image,
);
filter_window
.set_image("Filtered Depth", depth_image)
.unwrap();
}
}