66 lines
2.5 KiB
Rust
66 lines
2.5 KiB
Rust
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<f32>) -> Result<Self::Output, TensorError> {
|
|
// tract 的 run 会返回一个 Vec<TValue>,我们通常只需要第一个输出
|
|
// 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::<f32>().map_err(|_| {
|
|
TensorError::Engine("Tract 实体张量无法转换为 ndarray::ArrayD".to_string())
|
|
})?;
|
|
// 提前利用克隆(Clone)备份好当前未转维度前的真实 shape (Vec<usize>)
|
|
let shape_vec: Vec<usize> = 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::<Ix3>().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 {}
|