2010-03-04 66 views
1

类的功能:丑类接口定义

  1. 接收图像帧的序列,该序列是无限
  2. 检测帧中是否有运动。
  3. 按照一定的算法对运动帧进行分组。

到目前为止,该设计(非常愚蠢的):

class MotionDetector 
{ 
     //detect motion in the frame, return true if the group is captured. 
     //frameToDispose is the frame that need be dispose, or for further process. 
     public bool ProcessFrame(Frame in, out frameToDispose); 
    } 

消费者(片段):

public void Foo() 
{ 
    bool groupCaptured = motionDetector.ProcessFrame(nextFrame, out lastFrame); 

    if (IsStaticFrame(lastFrame)) { lastFrame.Dispose(); } 
    else { imagesArray.Add(lastFrame); } 

    if(groupCaptured) { processImageGroup(imagesArray); } 
} 

我觉得与MotionDetector的设计以下的不舒服:

  1. 获取图像组的方式。
  2. 处置静止帧的方法。
  3. 通知客户端该组捕获的方式。

您能否就该类的界面设计给出一些建议,以便客户端使用该类更容易和更优雅?

+0

究竟是什么感觉不舒服? – AxelEckenberger 2010-03-04 08:36:12

+0

@Obalix,编辑添加我不舒服的。 – Benny 2010-03-04 08:39:42

回答

1

我可能会做这样的事情:

public class MotionDetector 
{ 
    private IFrameGroupListener m_listener; 

    public MotionDetector(IFrameGroupListener listener) 
    { 
     m_listener = listener; 
    } 

    public void NewFrame(Frame f) 
    { 
     if(DetectMotion(f)) 
     { 
      var group = GetCaptureGroup(); 
      m_listener.ReceiveFrameList(group); 
     } 
    } 
} 

public interface IFrameGroupListener 
{ 
    void ReceiveFrameList(IList<Frame> captureGroup); 
} 

public class FramePump 
{ 
    private MotionDetector m_detector; 

    public FramePump(MotionDetector detector) 
    { 
     m_detector = detector; 
    } 

    public void DoFrame() 
    { 
     Frame f = GetFrameSomehow(); 
     m_detector.NewFrame(f); 
    } 

} 

我假设DetectMotion()存储帧,否则你必须保持在一个待定列表中,直到它的时间去摆脱它。无论如何,FramePump会从实际的设备/文件中获取单个帧。这是工作。 MotionDetector负责检测动作,并将动画组中的帧组传递给FrameGroupListener,然后完成它需要做的任何事情。

通过这种方式,这些类与责任很好地分离开来,很少以有状态的方式完成 - 所有状态都被本地化为各个类。由于这些调用都是无效的,所以如果需要,它们可以被调度到任意线程。

FramePump可能会在某种计时器循环中被触发。

我可能会考虑将分组算法分解为一个单独的类也有 - motiondetector类吐出每个帧以及bool指示是否检测到运动,然后MotionGrouper类将单独采取这些,并根据需要的任何算法吐出帧列表。 “检测运动”和“确定如何分组帧”显然是两项责任。但是,应该清楚在这种通用的流水线设计中如何进行重构。

1

如果我正确理解你的问题,你不喜欢你的班级的客户必须使用你提供的方法...
如何使框架处置类的属性而不是输出参数?

class MotionDetector{ 

    public bool PreProcessFrame(Frame in); 

    public Frame frameToDispose{ 
    get;   
    }  
} 

然后,你可以使用它像:

bool groupCaptured = motionDetector.ProcessFrame(nextFrame); 
if (IsStaticFrame(motionDetector.frameToDispose)){ 
    // ... 
} 

否则(如果是有意义的,你的应用程序),你可以这样做:

class MotionDetector{  
    // returns frame to dispose if sucessful, null otherwise 
    public Frame PreProcessFrame(Frame in); 
} 

编辑关于让消费者通过评论中建议的事件了解所拍摄的群组:

class GroupCapturedEventArgs : EventArgs{ 
    // put relevant information here... 
} 
class MotionDetector{ 
    public event EventHandler<GroupCapturedEventArgs> GroupCaptured; 
    // then somewhere in your code: 
    private vois SomeMethod() { 
    // a group captured 
    if (GroupCaptured != null) { 
     GroupCaptured (this,new GroupCapturedEventArgs(/*whatever*/)); 
    } 
    }  
} 
+0

好点,怎么样让消费者知道这个团队被抓获,以及如何获得团队? – Benny 2010-03-04 08:43:12

+0

第三个例子是最干净的IMO。有时候,当一个简单的null测试工作原理相同,并且更易于维护时,人们会挂起返回的布尔值。 – Chris 2010-03-04 08:43:26

+0

至于让消费者知道团队被捕获的问题,为什么不使用事件? – Chris 2010-03-04 08:44:03

3

消费者类正在做MotionDetector应该做的工作。也许MotionDetector构造器(或类中的某个方法)应该采用一串帧,并且这项工作应该在内部完成。算法运行后,该类应该只显示必要的图像数组。

+0

对不起,帧的序列是无限的。 – Benny 2010-03-04 08:50:19

+0

在这种情况下,它仍然可以使用流,但暴露一个不可变的IList 。 – 2010-03-04 08:56:01