2010-03-04 32 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