需要对 Rust 中的同一对象进行多次引用的管道架构

问题描述 投票:0回答:0

我目前正在学习 Rust,为了获得实践经验,我一直在玩一些小项目。

目前我正在做一个小型计算机视觉管道,用于进行多种不同的图像处理(目前是 QRDetection 和解码),并在屏幕上显示处理后的图像以及一些信息的表格。为此,我考虑了以下主要组成部分:

  • Stage:任何图像处理器都应实现的特征。
  • SourceStage:任何图像源都应实现的特征。
  • CameraSource:它实现了一个负责从相机中检索视频的 SourceStage。
  • QrDecoder:它实现了 Stage 特性,在 QR 码周围绘制一个矩形,保留最后一帧的任何 QR 信息.
  • PipelineManager:负责按顺序(目前)存储和传递图像通过不同的阶段,这些顺序可能在将来用于其他项目。
  • UIManager:显示所有 UI 组件,包括来自管道的已处理帧。

现在的主要流程是让 UIManager 拥有 PipelineManager,并在每一帧上运行管道(包含 CameraSource 和 QrDecoder)。

之后问题来了,我还想在UIManager拥有的表中显示最后一帧的QR信息,所以我需要在UIManager中保存一个QrDecoder的引用。 Stages 对象应该由 PipelineManager 拥有,但同一个对象可以被多次引用(不需要可变性)。

我能想到的解决这个问题的唯一方法是对每个阶段使用 Rc 的组合,并将 QRDecoder 传递给 UIManager 和 PipelineManager,但这似乎是不好的做法。

管道管理器

use opencv::{prelude::*};
use std::cell::{RefCell};
use std::rc::Rc;

pub trait Stage {
    fn process(&mut self, input: &mut Mat) -> Result<()>;
}

pub trait SourceStage {
    fn get_frame(&mut self) -> Result<Box<Mat>>;
}

pub struct CVPipelineManager{
    start_stage: Option<Rc<RefCell<dyn SourceStage>>>,
    stages: Vec<Rc<RefCell<dyn Stage>>>
}


impl CVPipelineManager{
    pub fn new() -> Self {
        Self {
            stages: Vec::new(),
            start_stage: None,
        }
    }

    pub fn add_stage(&mut self, stage: Rc<RefCell<dyn Stage>>){
        self.stages.push(stage);
    }

    pub fn process(&mut self) -> Result<Box<Mat>>{

        if let Some(ref mut start_stage) = self.start_stage {
            let mut frame = start_stage.borrow_mut().get_frame()?;
            self.process_image(frame.as_mut());
            return Ok(frame);
        }
        return Err(anyhow!("Process cannot be called if a start stage was not defined"));
    }

    pub fn process_image(&mut self, input: &mut Mat) -> Result<()> {
        for stage in self.stages.iter_mut() {
            stage.borrow_mut().process(input)?;
        }
        Ok(())
    }

此代码仅实现 PipelineManager 和所需的特征,以便更好地理解问题。

是否有更好的架构或者 Rust 是否提供了更好的工具来处理此类问题?我想不出任何其他方法来设计这个,而不会在实施新阶段时增加太多工作量。

rust design-patterns computer-vision software-design
© www.soinside.com 2019 - 2024. All rights reserved.