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:  };

所有的头文件都已列出,后面先给出程序的简单类结构图,然后再给出头文件对应的代码实现,最后再进行一些简单的测试。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值