use anyhow::{Result, bail, ensure};
use realsense_rust;
use realsense_rust::frame::{ColorFrame, PointsFrame};
use realsense_rust::pipeline::ActivePipeline;
use realsense_rust::{
config::Config,
context::Context,
frame::DepthFrame,
kind::{Rs2CameraInfo, Rs2Format, Rs2ProductLine, Rs2StreamKind},
pipeline::InactivePipeline,
};
use crate::data_types::intrinsic_info::IntrinsicInfo;
use std::process::{Command, Stdio};
use std::{collections::HashSet, convert::TryFrom, time::Duration};
use crate::backend::realsense::rs2_process_frame::{FrameProc, FrameProcBlock, create_color_image};
pub struct RealsenseCam {
pub cam_no: usize,
pipeline: ActivePipeline,
pcl_block: FrameProcBlock<PointsFrame>,
}
impl RealsenseCam {
pub fn initialise_raw(cam_no: usize) -> Result<Self, anyhow::Error> {
let (pipeline, config) = Self::setup(cam_no)?;
Ok(Self {
cam_no,
pipeline: pipeline.start(Some(config))?,
pcl_block: FrameProcBlock::make_raw_points_block(1)?,
})
}
fn setup(cam_no: usize) -> Result<(InactivePipeline, Config), anyhow::Error> {
let mut queried_devices = HashSet::new();
queried_devices.insert(Rs2ProductLine::D400);
let context = Context::new()?;
let devices = context.query_devices(queried_devices);
ensure!(!devices.is_empty(), "No devices found");
if cam_no > devices.len() {
bail!("Invalid camera selection");
}
let pipeline = InactivePipeline::try_from(&Context::new()?)?;
let mut config = Config::new();
config
.enable_device_from_serial(devices[cam_no].info(Rs2CameraInfo::SerialNumber).unwrap())?
.disable_all_streams()?
.enable_stream(Rs2StreamKind::Depth, None, 1280, 0, Rs2Format::Z16, 30)?
.enable_stream(Rs2StreamKind::Color, None, 1280, 0, Rs2Format::Rgb8, 30)?;
Ok((pipeline, config))
}
pub fn get_depth_pnts(&mut self, max_range: f32) -> Result<Vec<[f32; 3]>> {
let frame = self.pipeline.wait(None)?;
let mut depth_frame = frame.frames_of_type::<DepthFrame>();
if depth_frame.is_empty() {
bail!("No depth frame to read!");
}
self.pcl_block
.queue(depth_frame.pop().unwrap())
.expect("FAILED TO QUEUE DEPTH FRAME");
let point_frame: PointsFrame = self.pcl_block.wait(Duration::from_millis(1000))?;
let mut points: Vec<[f32; 3]> = vec![];
for vertex in point_frame.vertices().iter() {
let vertex = vertex.xyz;
if vertex[2] == 0.0 || vertex[2] > max_range {
continue;
}
points.push(vertex)
}
Ok(points)
}
pub fn get_image(&mut self, filename: &str) -> Result<(), anyhow::Error> {
let frame = self.pipeline.wait(None)?;
let color_frame = frame.frames_of_type::<ColorFrame>();
if color_frame.is_empty() {
bail!("No color frame to read!");
}
let image = create_color_image(color_frame.first().unwrap())?;
let fp = format!("appdata\\{}.png", filename);
image.save(fp)?;
println!("Image saved!");
Ok(())
}
pub fn get_intrinsics(&self) -> Result<IntrinsicInfo, anyhow::Error>{
let intrinsics = self.pipeline.profile().streams()[0].intrinsics()?;
Ok(IntrinsicInfo::create(
intrinsics.fx(),
intrinsics.fy(),
intrinsics.ppx(),
intrinsics.ppy(),
0.0
))
}
}