use crate::loader::{ModelLoader, ModelSession, ModelType}; use anyhow::Context; use ddddocr_core::error::{DdddError, Result}; use ddddocr_core::{DetEngine, DetOutput, InferenceEngine}; use ndarray::Ix3; use std::path::Path; use tract_onnx::prelude::{Graph, IntoTensor, RunnableModel, Tensor, TypedFact, TypedOp, tvec}; #[derive(Debug)] pub struct DetSession { pub session: RunnableModel, Graph>>, } impl ModelSession for DetSession { fn get_model_type(&self) -> ModelType { todo!() } fn desc(&self) -> String { "Detection Model 加载成功".to_string() } } impl DetSession { pub fn new

(model_path: P) -> Result where P: AsRef, { let session = ModelLoader::model_for_path(&model_path)?.session; Ok(Self { session }) } pub fn model_from_bytes(model_bytes: &[u8]) -> Result { let session = ModelLoader::model_from_bytes(model_bytes)?.session; Ok(Self { session }) } // pub fn inference(&self, tensor: Tensor) -> anyhow::Result { // // tract 的 run 会返回一个 Vec,我们通常只需要第一个输出 // // let result = self.ocr.run(tvec!(tensor.into()))?; // let mut result = self // .session // .run(tvec!(tensor.into())) // .context("执行模型推理失败")?; // println!("模型输出原始数据: {:?}", result); // Ok(result.swap_remove(0).into_tensor()) // } } impl InferenceEngine for DetSession { type Output = DetOutput; // 明确绑定 OCR 小枚举 fn inference(&self, input_array: ndarray::Array4) -> Result { // tract 的 run 会返回一个 Vec,我们通常只需要第一个输出 // let result = self.ocr.run(tvec!(tensor.into()))?; let tensor = Tensor::from(input_array); let mut result = self .session .run(tvec!(tensor.into())) .context("执行模型推理失败")?; println!("模型输出原始数据: {:?}", result); // Ok(result.swap_remove(0).into_tensor()) let raw_tensor = result.swap_remove(0).into_tensor(); let array_d = raw_tensor .into_array::() .context("Tract 实体张量无法转换为 ndarray::ArrayD")?; // 提前利用克隆(Clone)备份好当前未转维度前的真实 shape (Vec) let actual_shape = array_d.shape().to_vec(); let array3 = array_d .into_dimensionality::() .map_err(|_| DdddError::DimensionMismatch { expected: "3D 检测矩阵 [Batch, Box_Count, Box_Attributes]".to_string(), actual: actual_shape, // 优雅降维失败时动态捕获 })?; Ok(DetOutput::Detection(array3)) // 在引擎内部消化掉 DatumType 强耦合 } } impl DetEngine for DetSession {}