ITK 配準框架中的 Subject/Observer 模式及優化過程模擬演示-2

剩下的幾個頭文件如下:

6.ITK 中對數據成員的設置大量使用了宏定義,不但代碼簡潔,而且風格統一,非常方便,我這裏只演示了三個宏的使用,具體看代碼:

   1:   
   2:  //MyTypeMacro.h
   3:  #pragma once
   4:   
   5:  //宏定義, ITK 中類成員函數使用了大量的宏定義, 這裏示例幾個個比較簡單實用的:
   6:   
   7:  //運行時類型識別, 該宏在類中創建一個成員函數: virtual const char* GetNameOfClass() const;
   8:  #define MyTypeMacro(thisClass, superclass) /
   9:      virtual const char *GetNameOfClass() const /
  10:      {    return #thisClass;    } 
  11:   
  12:  //Set 宏, 該宏得到成員函數: virtual void Setname(type* _arg);
  13:  //這樣可以使我們定義類時, 代碼量大爲減少, 且可以保持代碼風格的一致性
  14:  #define MySetObjectMacro(name,type) /
  15:  virtual void Set##name (type* _arg) /
  16:  { /
  17:      if (this->m_##name != _arg) /
  18:      { /
  19:          this->m_##name = _arg; /
  20:      } /
  21:  } 
  22:  //以 MyRegistrationMethod 中:  MySetObjectMacro( Optimizer,  OptimizerType ); 展開爲例:
  23:  //virtual void SetOptimizer (OptimizerType* _arg)
  24:  //{
  25:  //    if (this->m_Optimizer != _arg)  //## 字符串連接符, 預編譯
  26:  //  { 
  27:  //        this->m_Optimizer = _arg;
  28:  //    } 
  29:  //} 
  30:   
  31:   
  32:  //Get 宏, 該宏會得到成員函數: virtual type* Getname();
  33:  #define MyGetObjectMacro(name,type) /
  34:      virtual type* Get##name () /
  35:      { /
  36:          return this->m_##name; /
  37:      }

 

7.Optimizer 優化函數模擬,上面提到過,圖像配準的本質是個函數優化的問題。爲了方便演示,我這裏基本沒做什麼內容。

我的 Optimimzer 要完成的功能爲:給定一個初值,使其值經過迭代達到 100。優化過程的每一次迭代,根據得到的測度值進行修改,如果測度值爲正,則將當前值 + step,即加上一個值。否則將其減 1。過程非常簡單,基本什麼都沒做,但我認爲它已經能夠演示圖像配準框架的優化過程。

Optimizer 類代碼中的一些方法,如 StartOptimization()、GetValue() 都是模仿 ITK 中的調用過程,並進行大大的簡化,只保留了一些比較明顯的調用順序。

   1:  #pragma once
   2:  #include "MyTypeMacro.h"
   3:  #include "MySimpleMetric.h"
   4:  #include "MyObject.h"
   5:   
   6:  //模擬配準框架中的優化組件 Optimizer
   7:  //圖像配準本質是一個優化迭代過程, 每次迭代修改參數空間,並觸發 MyIterationEvent 事件
   8:  //客戶註冊 MyIterationEvent 爲感興趣事件, 輸出一些信息跟蹤迭代過程
   9:   
  10:  //MyOptimizer: 優化方法基類 
  11:  class MyOptimizer : public MyObject 
  12:  {
  13:  public:
  14:      typedef MyOptimizer                 Self;
  15:      typedef MyObject                    Superclass;
  16:      typedef MyOptimizer*                Pointer;
  17:      typedef const MyOptimizer*             ConstPointer;
  18:   
  19:      //運行時類型識別
  20:      MyTypeMacro(MyOptimizer, MyObject);
  21:   
  22:      //CostFunction, Measure type, ParametersType
  23:      typedef  MyCostFunction                      CostFunctionType;        //代價函數
  24:      typedef  CostFunctionType::Pointer          CostFunctionPointer;    
  25:      typedef  CostFunctionType::MeasureType      MeasureType;            //測度類型
  26:      typedef  CostFunctionType::ParametersType ParametersType;        //參數類型
  27:   
  28:      //Set/Get 代價函數, 即相似性測度組件.
  29:      virtual void SetCostFunction(CostFunctionType * costFunction);
  30:      virtual CostFunctionPointer GetCostFunction() const;
  31:   
  32:      //設置初始優化值
  33:      void SetInitialPosition(ParametersType initialPosition);
  34:      
  35:      //取得當前優化的參數值
  36:      ParametersType GetCurrentPosition() const;
  37:   
  38:      //Set/Get 最終值
  39:      void SetLastPosition(ParametersType LastPosition);
  40:      ParametersType GetLastPosition() const;
  41:   
  42:      //Start, Stop optimization.
  43:      virtual void StartOptimization();    
  44:      virtual void StopOptimization();
  45:   
  46:      //設置迭代次數限制; 返回當前已迭代次數
  47:      void SetNumberOfIteration(unsigned long max);
  48:      unsigned long GetCurrentIteration() const;
  49:   
  50:      //返回當前參數空間的測度值,它調用代價函數進行計算
  51:      MeasureType GetValue() const;
  52:  protected:
  53:      MyOptimizer();
  54:      virtual ~MyOptimizer() {};
  55:      void PrintSelf(std::ostream& os, MyIndent indent) const;
  56:   
  57:      //迭代一次, 修改參數值,子類根據具體的優化策略實現
  58:      virtual void AdvanceOneStep() = 0;
  59:   
  60:      //參數空間
  61:      ParametersType            m_InitialPosition;     //初始化參數值
  62:      ParametersType            m_CurrentPosition;     //當前優化值
  63:      ParametersType            m_LastPosition;         //最終優化值
  64:   
  65:      //迭代
  66:      bool                    m_Stop;                 //迭代停止標識
  67:      unsigned long            m_CurrentIteration;  //當前迭代次數
  68:      unsigned long            m_NumberOfIterations;//迭代次數最大限制
  69:   
  70:      //測度值, 測度值越小, 表示參數越接近結果
  71:      MeasureType                m_Value;             //當前測度值
  72:   
  73:      //使用的代價函數
  74:      CostFunctionPointer        m_CostFunction;         //代價函數
  75:   
  76:  private:
  77:      MyOptimizer(const Self&);                
  78:      void operator=(const Self&);    
  79:  };
  80:   
  81:  //具體的優化方法類:
  82:  //這裏其實沒有做什麼實質性工作,爲了演示: 只是爲了使參數 m_LastPosition 儘可能地接近 100
  83:  class MyConcreteOptimizer : public MyOptimizer
  84:  {
  85:  public:
  86:      typedef MyConcreteOptimizer            Self;
  87:      typedef MyOptimizer                 Superclass;
  88:      typedef MyConcreteOptimizer*        Pointer;
  89:      typedef MyConcreteOptimizer* const    ConstPointer;
  90:   
  91:      //創建一個 MyConcreteOptimizer 實例
  92:      static Self* New();
  93:   
  94:      //Delete()
  95:      virtual void Delete();
  96:   
  97:      //運行時類型識別
  98:      MyTypeMacro( MyConcreteOptimizer, MyOptimizer );
  99:      
 100:      typedef Superclass::ParametersType    ParametersType;
 101:   
 102:      //設置前進步長
 103:      void SetStepLength(ParametersType step); 
 104:   
 105:  protected:
 106:      MyConcreteOptimizer();
 107:      virtual ~MyConcreteOptimizer() {};
 108:          
 109:      void PrintSelf(std::ostream& os, MyIndent indent) const;
 110:   
 111:      //前進一步, 迭代一次
 112:      //這裏每次迭代: m_CurrentPosition = m_CurrentPosition + m_StepLength;
 113:      //或者當測度值爲負時: m_CurrentPosition = m_CurrentPosition - 1;
 114:      //只爲演示, 使 m_CurrentPosition 達到 100 爲目標
 115:      virtual void AdvanceOneStep();
 116:   
 117:  private:
 118:      MyConcreteOptimizer(const Self&);
 119:      void operator=(const Self&); 
 120:   
 121:      ParametersType    m_StepLength;    //默認爲 2, 構造函數中設置
 122:  };

 

8.Metric 該類模擬相似性測度組件的功能,通過將傳入的參數值與 100 相減,得到測度值。測度值爲正時,越小則表明參數越接近目標。爲負時,表示參數超過目標。優化函數根據測度值對參數進行不同的修改。

   1:   
   2:  //MySimpleMetric.h
   3:  #pragma once
   4:  #include "MyTypeMacro.h"
   5:  #include "MyObject.h"
   6:   
   7:  //模擬相似性測度組件; 優化組件進行一次迭代, 便得到一新的參數
   8:  //將該參數傳遞到測度組件, 測度組件根據一定的準則對該參數空間進行評估
   9:   
  10:  //基類, 代價函數
  11:  class MyCostFunction : public MyObject 
  12:  {
  13:  public:
  14:      typedef MyCostFunction              Self;
  15:      typedef MyObject                    Superclass;
  16:      typedef MyCostFunction*                Pointer;
  17:      typedef const MyCostFunction*         ConstPointer;
  18:   
  19:      //run time type information
  20:      MyTypeMacro(MyCostFunction, MyObject);
  21:   
  22:      typedef        int        ParametersType;
  23:      typedef        int        MeasureType;
  24:   
  25:      //初始化
  26:      virtual void Initialize(void);
  27:      
  28:      //根據傳入的參數, 計算測度值
  29:      virtual MeasureType GetValue(const ParametersType &) = 0;
  30:          
  31:      //返回當前測度值
  32:      virtual MeasureType GetValue() const;
  33:  protected:
  34:      MyCostFunction() {    };
  35:      virtual ~MyCostFunction() {};
  36:      void PrintSelf(std::ostream& os, MyIndent indent) const;
  37:   
  38:      MeasureType        m_Value;
  39:  private:
  40:      MyCostFunction(const Self&);
  41:      void operator=(const Self&);
  42:  };
  43:   
  44:  //模擬具體的測度組件功能
  45:  class MySimpleMetric : public MyCostFunction 
  46:  {
  47:  public:
  48:      typedef MySimpleMetric                Self;
  49:      typedef MyCostFunction                Superclass;
  50:      typedef MySimpleMetric*                Pointer;
  51:      typedef MySimpleMetric* const        ConstPointer;
  52:   
  53:      //New()
  54:      static Self* New() { return new Self; }
  55:      //Delete()
  56:      void Delete() {    delete this;    }
  57:   
  58:      //運行時類型識別
  59:      MyTypeMacro( MySimpleMetric, MyCostFunction);
  60:   
  61:      typedef Superclass::ParametersType    ParametersType;
  62:      typedef Superclass::MeasureType        MeasureType;
  63:   
  64:      //根據輸入參數, 計算相似性測度值, 這裏只是進行簡單的功能演示
  65:      //這裏將 m_Value = 100 - parameters; 測度值越小,表明越接近 100;
  66:      //但是當 m_Value < 0 時, 表明大於 100, 根據測度值, 優化函數進行不同的優化策略.
  67:      MeasureType GetValue(const ParametersType & parameters);
  68:   
  69:  protected:
  70:      MySimpleMetric(){};
  71:      virtual ~MySimpleMetric(){};
  72:      void PrintSelf(std::ostream& os, MyIndent indent) const;
  73:   
  74:  private:
  75:      MySimpleMetric(const Self&); 
  76:      void operator=(const Self&); 
  77:  };

 

9.該類用於連接 metric 與 optimizer,用於模擬 ITK 配準框架中的 ImageRegistrationMethod 類;ImageRegistrationMethod  用於連接各個組件,並進行適當的初始化,使管道達到一致的狀態,協調管道上各個組件的執行。

   1:   
   2:  //MyRegistrationMethod.h
   3:  #pragma once
   4:  #include "MyTypeMacro.h"
   5:  #include "MyObject.h"
   6:  #include "MySimpleMetric.h"
   7:  #include "MyOptimizer.h"
   8:   
   9:  //MyRegistrationMethod: 模擬配準框架的 ImageRegistrationMethod 類
  10:  //ImageRegistrationMethod 用來連接各個配準組件
  11:  //這裏, MyRegistrationMethod 只是進行簡單的模擬, 連接 MyOptimizer 與 MySimpleMetric
  12:  //去掉了 Transform, Interpolator, 以及輸入輸出圖像, 只爲演示
  13:  class MyRegistrationMethod : public MyObject
  14:  {
  15:  public:
  16:      typedef MyRegistrationMethod         Self;
  17:      typedef MyObject                     Superclass;
  18:      typedef MyRegistrationMethod*         Pointer;
  19:      typedef const MyRegistrationMethod*  ConstPointer;
  20:   
  21:      //創建一個 ImageRegistrationMethod 實例
  22:      static Pointer New();
  23:   
  24:      //Delete()
  25:      virtual void Delete();
  26:   
  27:      //運行時類型識別
  28:      MyTypeMacro(MyRegistrationMethod, MyObject);
  29:   
  30:      //代價函數, 模擬相似性測度組件的功能:
  31:      typedef MyCostFunction                  MetricType;
  32:      typedef MetricType::Pointer              MetricPointer;
  33:      typedef MetricType::ParametersType    ParametersType;
  34:   
  35:      //單值優化函數類型
  36:      typedef   MyOptimizer                  OptimizerType;
  37:      typedef      OptimizerType::Pointer      OptimizerPointer;
  38:   
  39:   
  40:      //開始執行配準過程
  41:      void StartRegistration(void);
  42:   
  43:      //開始執行優化過程
  44:      void StartOptimization(void);
  45:   
  46:      //以下幾個宏設置 Optimizer 及 Metric 等,也就是在程序中調用函數 SetOptimizer()
  47:      //Set/Get the Optimizer.
  48:      MySetObjectMacro( Optimizer,  OptimizerType );
  49:      MyGetObjectMacro( Optimizer,  OptimizerType );
  50:      //以上兩個宏會得到如下兩個函數:
  51:      //virtual void SetOptimizer(OptimizerType* optimizer); 
  52:      //virtual OptimizerType* GetOptimizer();
  53:   
  54:      //Set/Get the Metric. 
  55:      MySetObjectMacro( Metric, MetricType );
  56:      MyGetObjectMacro( Metric, MetricType );
  57:   
  58:      //Get Last Parameters
  59:      virtual ParametersType GetLastParameters() const;
  60:   
  61:      //初始化各個組件
  62:      virtual void Initialize();
  63:   
  64:      //更新, 觸發管道的執行, 模擬 ITK 管道的更新機制
  65:      virtual void Update();
  66:   
  67:  protected:
  68:      MyRegistrationMethod(){};
  69:      virtual ~MyRegistrationMethod();
  70:      void PrintSelf(std::ostream& os, MyIndent indent) const;
  71:   
  72:      //ITK 配準框架中, 這個函數是非常重要,它由管道觸發,調用 StartRegistration() 開始配準過程
  73:      void  GenerateData ();
  74:   
  75:      //Provides derived classes with the ability to set this private var */
  76:      //MySetMacro( LastTransformParameters, ParametersType );
  77:   
  78:  private:
  79:      MyRegistrationMethod(const Self&);
  80:      void operator=(const Self&);
  81:   
  82:      MetricPointer                  m_Metric;
  83:      OptimizerPointer               m_Optimizer;
  84:   
  85:      ParametersType                 m_LastParameters;
  86:  };

所有的頭文件都已列出,後面先給出程序的簡單類結構圖,然後再給出頭文件對應的代碼實現,最後再進行一些簡單的測試。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章