use crate::types::Session; use ddddocr_core::DetOutput; use ddddocr_core::error::{Result, TensorError}; use ddddocr_core::traits::{DetEngine, InferenceEngine}; use ndarray::Ix3; use ort::inputs; use ort::value::TensorRef; // use tract_onnx::prelude::{tvec, IntoTensor, Tensor}; #[derive(Debug)] pub struct DetRuntime { pub session: Session, } impl DetRuntime { pub fn new(session: Session) -> Self { Self { session } } } impl InferenceEngine for DetRuntime { type Output = DetOutput; // 明确绑定 OCR 小枚举 fn inference(&self, input_array: ndarray::Array4) -> Result { // tract 的 run 会返回一个 Vec,我们通常只需要第一个输出 // let result = self.ocr.run(tvec!(tensor.into()))?; let mut session_guard = self .session .lock() .map_err(|_| TensorError::Engine("获取 Session 锁失败 (Poisoned)".to_string()))?; let result = session_guard .run(inputs![TensorRef::from_array_view(&input_array).map_err( |e| TensorError::Engine(format!("构建输入失败: {e}")) )?]) .map_err(|e| TensorError::Engine(format!("执行模型推理失败: {e}")))?; // .context("执行模型推理失败")?; println!("模型输出原始数据: {:?}", result); // Ok(result.swap_remove(0).into_tensor()) let raw_value = &result[0]; // raw_tensor.into_plain_array()? let (shape_ref, slice) = raw_value.try_extract_tensor::().map_err(|_| { TensorError::Engine("Tract 实体张量无法转换为 ndarray::ArrayD".to_string()) })?; // 提前利用克隆(Clone)备份好当前未转维度前的真实 shape (Vec) let shape_vec: Vec = shape_ref.to_vec().iter().map(|v| *v as usize).collect(); let shape_vec_slice = shape_vec.as_slice(); let view = ndarray::ArrayViewD::from_shape(shape_vec_slice, slice) .map_err(|_| TensorError::Engine("构建 ndarray ArrayViewD 失败".to_string()))?; let array3 = view.to_owned().into_dimensionality::().map_err(|_| { TensorError::DimensionMismatch { expected: "3D 检测矩阵 [Batch, Box_Count, Box_Attributes]".to_string(), actual: shape_vec, // 优雅降维失败时动态捕获 } })?; Ok(DetOutput::Detection(array3)) // 在引擎内部消化掉 DatumType 强耦合 } } impl DetEngine for DetRuntime {}