ITK 配准框架中的 Subject/Observer 模式及优化过程模拟演示-4

其余几个头文件对应的代码实现如下:

7.Optimizer 优化函数类:

   1:   
   2:  //MyOptimizer.cpp
   3:  #include "MyOptimizer.h"
   4:   
   5:  //MyOptimizer
   6:  MyOptimizer::MyOptimizer()
   7:  {
   8:      m_InitialPosition    = 0;
   9:      m_CurrentPosition     = 0;
  10:      m_LastPosition         = 0;
  11:   
  12:      m_Stop = false;
  13:      m_CurrentIteration   = 0;
  14:      m_NumberOfIterations = 0;
  15:   
  16:      m_Value                 = 0;
  17:  }
  18:   
  19:  //Set/Get the cost function.
  20:  void MyOptimizer::SetCostFunction(CostFunctionType * costFunction)
  21:  {
  22:      m_CostFunction  = costFunction;
  23:      m_Value            = 100;            //初始测度值, 将其设为一较大值
  24:  }
  25:  //
  26:  MyOptimizer::CostFunctionPointer MyOptimizer::GetCostFunction() const
  27:  {
  28:      return m_CostFunction;
  29:  }
  30:  //设置初始化值
  31:  void MyOptimizer::SetInitialPosition(ParametersType initialPosition)
  32:  {
  33:      m_InitialPosition = initialPosition;
  34:      m_CurrentPosition = m_InitialPosition;
  35:  }
  36:  //取得当前优化的参数值
  37:  MyOptimizer::ParametersType MyOptimizer::GetCurrentPosition() const 
  38:  { 
  39:      return m_CurrentPosition; 
  40:  }
  41:  //设置, 取得最终参数值
  42:  void MyOptimizer::SetLastPosition(ParametersType LastPosition)
  43:  {
  44:      m_LastPosition = LastPosition;
  45:  }
  46:  MyOptimizer::ParametersType MyOptimizer::GetLastPosition() const
  47:  {
  48:      return m_LastPosition;
  49:  }
  50:  //设置迭代次数上限
  51:  void MyOptimizer::SetNumberOfIteration(unsigned long max)
  52:  {
  53:      m_NumberOfIterations = max;
  54:  }
  55:  //返回当前迭代次数
  56:  unsigned long MyOptimizer::GetCurrentIteration() const
  57:  {
  58:      return m_CurrentIteration;
  59:  }
  60:   
  61:  //返回当前测度值
  62:  MyOptimizer::MeasureType MyOptimizer::GetValue() const
  63:  {
  64:      return this->GetCostFunction()->GetValue(m_CurrentPosition);
  65:  }
  66:   
  67:  //开始优化过程:
  68:  //优化是一个迭代的过程, 每进行一次迭代, 便触发 MyIterationEvent() 事件
  69:  void MyOptimizer::StartOptimization() 
  70:  {    
  71:      //进行适当初始化
  72:      m_CurrentIteration = 0;
  73:      m_Stop = false;
  74:   
  75:      //优化开始,开始进行迭代, 触发 StartEvent() 事件.
  76:      this->InvokeEvent(MyStartEvent());
  77:   
  78:      while(!m_Stop)
  79:      {
  80:          //迭代次数达到最在限制
  81:          if(m_CurrentIteration >= m_NumberOfIterations)
  82:          {
  83:              this->StopOptimization();
  84:              break;
  85:          }
  86:          
  87:          //根据当前参数空间, 计算测度值
  88:          m_Value = m_CostFunction->GetValue( m_CurrentPosition );
  89:      
  90:          //前进一步, 迭代一次, 根据优化策略以及当前参数值计算出新的参数值
  91:          m_CurrentIteration++;
  92:          this->AdvanceOneStep();
  93:      }
  94:  };
  95:   
  96:  //停止优化过程
  97:  void MyOptimizer::StopOptimization()
  98:  {
  99:      //优化过程结束,停止迭代, 触发 EndEvent() 事件
 100:      m_Stop = true;
 101:      m_LastPosition = m_CurrentPosition;
 102:      this->InvokeEvent( MyEndEvent() );
 103:  }
 104:   
 105:  //打印相关信息
 106:  void MyOptimizer::PrintSelf( std::ostream& os, MyIndent indent ) const
 107:  {
 108:      Superclass::PrintSelf(os, indent);
 109:   
 110:      MyIndent nextIndent = indent.GetNextIndent();
 111:   
 112:      os << std::endl << nextIndent << "SomeParameters:  " << std::endl;
 113:      os << nextIndent << "CostFunction       =   " 
 114:          << m_CostFunction->GetNameOfClass() << std::endl;
 115:      os << nextIndent << "InitialPosition    =   " 
 116:          << m_InitialPosition << std::endl;
 117:      os << nextIndent << "CurrentPosition    =   " 
 118:          << m_CurrentPosition << std::endl;
 119:      os << nextIndent << "NumberOfIteration  =   " 
 120:          << m_NumberOfIterations << std::endl;
 121:      os << nextIndent << "CurrentMetricValue =   " 
 122:          << m_Value << std::endl;
 123:  }
 124:   
 125:  ////////////////////
 126:  //MyConcreteOptimizer, 具体的优化策略子类, 实现优化修改参数的策略
 127:  //New()
 128:  MyConcreteOptimizer* MyConcreteOptimizer::New(){ return new Self; }
 129:   
 130:  //Delete()
 131:  void MyConcreteOptimizer::Delete(){ delete this; }
 132:   
 133:  //
 134:  MyConcreteOptimizer::MyConcreteOptimizer()
 135:  {
 136:      m_StepLength = 2;    //前进步长, 默认为 2
 137:  }
 138:  void MyConcreteOptimizer::SetStepLength(ParametersType step)
 139:  {
 140:      m_StepLength = step;
 141:  }
 142:   
 143:  //前进一步, 迭代一次, 这里只为了演示,进行如下功能:
 144:  //使 m_CurrentPosition = 100; 
 145:  void MyConcreteOptimizer::AdvanceOneStep()
 146:  {
 147:      if(m_Value == 0)
 148:      {
 149:          this->StopOptimization();
 150:          return;
 151:      }
 152:   
 153:      //测度值越小, 表明越接近目标
 154:      //但是如果测度值为负, 则减少 m_CurrentPosition
 155:      if(m_Value < 0)
 156:      {
 157:          m_CurrentPosition = m_CurrentPosition - 1;
 158:      }
 159:      else
 160:      {
 161:          m_CurrentPosition = m_CurrentPosition + m_StepLength;
 162:      }
 163:      
 164:      this->InvokeEvent( MyIterationEvent() );
 165:  }
 166:   
 167:  //打印相关信息
 168:  void MyConcreteOptimizer::PrintSelf( std::ostream& os, MyIndent indent ) const
 169:  {
 170:      Superclass::PrintSelf(os, indent);
 171:   
 172:      MyIndent nextIndent = indent.GetNextIndent();
 173:      os << nextIndent  << "StepLength         =   " 
 174:          << m_StepLength << std::endl << std::endl;
 175:  }

8.Metric 相似性测度模拟类:

   1:  //MySimpleMetric.cpp
   2:  #include "MySimpleMetric.h"
   3:   
   4:  //
   5:  void MyCostFunction::Initialize(void)
   6:  {
   7:      m_Value = 100;
   8:  }
   9:  MyCostFunction::MeasureType MyCostFunction::GetValue() const
  10:  {
  11:      return m_Value;
  12:  }
  13:  void MyCostFunction::PrintSelf(std::ostream& os, MyIndent indent) const
  14:  {
  15:      Superclass::PrintSelf(os, indent);
  16:   
  17:      MyIndent nextIndent = indent.GetNextIndent();
  18:      std::cout << nextIndent << "Current MetricValue = " << GetValue() << std::endl;
  19:  }
  20:   
  21:  //根据输入参数, 计算相似性测度值, 这里只是进行简单的功能演示
  22:  //这里将传入的值与 100 相比, 当最接近 100 时, 测度值最小.
  23:  //当返回的测度值为 0 时, 表明大于 100, 这时需要在优化函数中减小参数
  24:  MySimpleMetric::MeasureType 
  25:  MySimpleMetric::GetValue(const ParametersType& parameters)
  26:  {
  27:      return m_Value = 100 - parameters;  
  28:  }
  29:  //
  30:  void MySimpleMetric::PrintSelf(std::ostream& os, MyIndent indent) const
  31:  {
  32:      Superclass::PrintSelf(os, indent);
  33:      os << std::endl;
  34:  }

9.MyRegistrationMethod 连接各个组件:

   1:  //MyRegistrationMethod.cpp
   2:  #include "MyRegistrationMethod.h"
   3:   
   4:  //
   5:  MyRegistrationMethod::~MyRegistrationMethod()
   6:  {
   7:      m_Metric    = NULL;
   8:      m_Optimizer = NULL;
   9:  }
  10:  //New() 创建对象实例
  11:  MyRegistrationMethod* MyRegistrationMethod::New()
  12:  {
  13:      return new Self;
  14:  }
  15:   
  16:  //Delete()
  17:  void MyRegistrationMethod::Delete()
  18:  {
  19:      delete this;
  20:  }
  21:  MyRegistrationMethod::ParametersType 
  22:  MyRegistrationMethod::GetLastParameters() const
  23:  {
  24:      return m_Optimizer->GetLastPosition();
  25:  }
  26:  //初始化各个组件
  27:  void MyRegistrationMethod::Initialize()
  28:  {
  29:      if ( !m_Metric ){
  30:          std::cout <<"Metric is not present" << std::endl;
  31:      }
  32:      if ( !m_Optimizer ){
  33:          std::cout << "Optimizer is not present" << std::endl;
  34:      }
  35:   
  36:      //初始化配准框架的各个组件, 这里为了模拟省略了大部分内容
  37:      m_Metric->Initialize();  
  38:      m_Optimizer->SetCostFunction( m_Metric ); 
  39:  }
  40:   
  41:  //ITK 的管道机制中, 调用管道上一个组件的 Update() 会更新管道, 触发管道的执行
  42:  //这里只为模拟,以展示 ITK 配准框架的大体过程, 它调用了 GenerateData() 以生成数据
  43:  void MyRegistrationMethod::Update()
  44:  {
  45:      this->GenerateData();
  46:  }
  47:   
  48:  //ITK 配准框架中, 这个函数是非常重要,它由管道触发,生成输出数据
  49:  //它调用了 StartRegistration() 开始配准过程, StartRegistration 进行适当的准备后又调用了
  50:  //Initialize() 进行必要初始化, 然后调用 StartOptimization() 开始优化过程
  51:  void MyRegistrationMethod::GenerateData ()
  52:  {
  53:      this->StartRegistration();
  54:  }
  55:  //
  56:  void MyRegistrationMethod::StartRegistration ()
  57:  {
  58:      this->Initialize();
  59:      this->StartOptimization();
  60:  }
  61:   
  62:  //StartOptimization 又调用了其指针成员 m_Optimizer 的同名函数
  63:  void MyRegistrationMethod::StartOptimization(void)
  64:  {
  65:      m_Optimizer->StartOptimization();
  66:  }
  67:   
  68:  //打印自身相关信息:
  69:  void MyRegistrationMethod::PrintSelf(std::ostream& os, MyIndent indent) const
  70:  {    
  71:      Superclass::PrintSelf( os, indent );
  72:   
  73:      MyIndent nextIndent = indent.GetNextIndent();
  74:      os << nextIndent << "Metric:    " << typeid(m_Metric).name() << std::endl;
  75:      os << nextIndent << "Optimizer: " << typeid(m_Optimizer).name() << std::endl;
  76:  }

10. test 测试代码,这里只测试了用于演示使用 Subject/Observer 模式监视优化迭代过程的代码:

   1:   
   2:  //test.cpp
   3:  #include "MyCommand.h"
   4:  #include "MyRegistrationMethod.h"
   5:  #include <iomanip>
   6:  #include <iostream>
   7:   
   8:  //客户定义一个具体的 Command 子类, 并实现其成员函数 Execute()
   9:  //Exectue() 功能相当于一个回调函数(callback)
  10:  //所以只应该完成一些简单的任务, 一般情况下使用 Command 监视迭代过程
  11:  //而在多分辨策略情况下, 使用 Command 在不同级间改变优化策略,这个问题以后再研究.
  12:  class MyCommandIterationUpdate : public MyCommand
  13:  {
  14:  public:
  15:      typedef  MyCommandIterationUpdate            Self;
  16:      typedef  MyCommand                            Superclass;
  17:      typedef  MyCommandIterationUpdate*            Pointer;
  18:      typedef  MyCommandIterationUpdate* const    ConstPointer;
  19:   
  20:      //New(), itk 中 New() 为宏, 通过对象工厂创建对象
  21:      //并使用引用计数与智能指针保证对象只有一个真正的实例, 减少空间占用
  22:      //关于智能指针与引用计数,以及使用对象工厂创建对象, 另外再进行专门的演示
  23:      static Self* New(){    return new Self; };
  24:      
  25:      //Delete()
  26:      virtual void Delete() { delete this; }
  27:   
  28:  protected:
  29:      MyCommandIterationUpdate() {    };
  30:   
  31:  public:
  32:      typedef MyConcreteOptimizer     OptimizerType;
  33:      typedef const OptimizerType     *OptimizerPointer;
  34:   
  35:      void Execute(MyObject *caller, const MyEventObject & event)
  36:      {
  37:          Execute( (const MyObject *)caller, event);
  38:      }
  39:      void Execute(const MyObject * object, const MyEventObject & event)
  40:      {
  41:          OptimizerPointer optimizer = dynamic_cast< OptimizerPointer >( object );
  42:   
  43:          //检查 MyCommandIterationUpdate 是否观察该事件
  44:          //主程序中注册了 Start, End, Iteration 三个感兴趣事件
  45:          if( !MyStartEvent().CheckEvent( &event ) && !MyEndEvent().CheckEvent( &event) &&
  46:              !MyIterationEvent().CheckEvent( &event ) )
  47:          {
  48:              std::cout << "I doesn't observe the event: " << event.GetEventName() << std::endl;
  49:              return;
  50:          }
  51:          if( MyStartEvent().CheckEvent( &event ) ){
  52:              std::cout << "StartOptimization:   ";
  53:              std::cout << "InitialPosition  = "   
  54:                  << std::setw(3) << optimizer->GetCurrentPosition();
  55:              std::cout << "   CurrentIteration = " 
  56:                  << std::setw(3) << optimizer->GetCurrentIteration();
  57:              std::cout << "   MetricValue = "      
  58:                  << std::setw(3) << optimizer->GetValue() << std::endl << std::endl;
  59:          }
  60:          if( MyEndEvent().CheckEvent( &event ) ){
  61:              std::cout << std::endl 
  62:                  << "StopOptimization......  End." << std::endl << std::endl;
  63:          }
  64:          if( MyIterationEvent().CheckEvent( &event ) )
  65:          {
  66:              std::cout << "MyIterationEvent:    ";
  67:              std::cout << "CurrentPosition  = "   
  68:                  << std::setw(3) << optimizer->GetCurrentPosition();
  69:              std::cout << "   CurrentIteration = " 
  70:                  << std::setw(3) << optimizer->GetCurrentIteration();
  71:              std::cout << "   MetricValue = "      
  72:                  << std::setw(3) << optimizer->GetValue() << std::endl;
  73:          }
  74:      }
  75:  };
  76:   
  77:  int main()
  78:  {
  79:      //1.声明并定义相关组件, 这里只是简单模拟了: 相似性测度, 优化, 配准方法组件
  80:      typedef MySimpleMetric                    metricType;
  81:      typedef MyConcreteOptimizer                optimizerType;
  82:      typedef MyRegistrationMethod            registrationType; //用于连接其它各个组件
  83:      
  84:      metricType::Pointer          metric        = metricType::New();
  85:      optimizerType::Pointer      optimizer        = optimizerType::New();
  86:      registrationType::Pointer registration    = registrationType::New();
  87:   
  88:      //2.连接各个组件:
  89:      registration->SetMetric(    metric     );
  90:      registration->SetOptimizer( optimizer);
  91:   
  92:      //3.声明并定义一个 Command 实例, 输出迭代执行过程
  93:      MyCommandIterationUpdate::Pointer observer = MyCommandIterationUpdate::New();
  94:   
  95:      //4.注册观察者以及其感兴趣的事件
  96:      optimizer->AddObserver(MyStartEvent(), observer);
  97:      optimizer->AddObserver(MyIterationEvent(), observer);
  98:      optimizer->AddObserver(MyEndEvent(), observer);
  99:   
 100:      //5.进行适当的初始设置
 101:      typedef registrationType::ParametersType ParametersType;
 102:   
 103:      //初始值, 这里随便给一个初值; 最终目的是使其达到 100
 104:      ParametersType initialPosition = 9;
 105:      optimizer->SetInitialPosition(initialPosition);
 106:      
 107:      //前进步长, 程序中默认值为 2 
 108:      ParametersType stepLength = 5;
 109:      optimizer->SetStepLength(stepLength);
 110:   
 111:      //设置最大迭代次数限制
 112:      optimizer->SetNumberOfIteration(50);
 113:   
 114:      ///////////////////////
 115:      //6.Update(), 开始优化迭代过程
 116:      registration->Update();
 117:      ///////////////////////
 118:   
 119:      //7.取得最后结果:
 120:      ParametersType finalParameters = registration->GetLastParameters();
 121:      const unsigned int numberOfIterations = optimizer->GetCurrentIteration();
 122:      const int bestValue = optimizer->GetValue();
 123:   
 124:      std::cout << "|----------------------------------------" << std::endl;
 125:      std::cout << "Result = " << std::endl;
 126:      std::cout << "   LastPosition  = " << finalParameters    << std::endl;
 127:      std::cout << "   Iterations    = " << numberOfIterations << std::endl;
 128:      std::cout << "   Metric value  = " << bestValue          << std::endl;
 129:      std::cout << "|----------------------------------------" << std::endl;
 130:      std::cout << std::endl;
 131:   
 132:      //打印一些相关的信息, 测试 Print() 函数:
 133:      std::cout << "Print some information about registrationMethod: " << std::endl;
 134:      registration->Print(std::cout, 0);
 135:   
 136:      std::cout << "/nNext Print some information about the optimizer: " << std::endl;
 137:      optimizer->Print(std::cout, 0);
 138:   
 139:      //这里没有使用智能指针,所以必须手动销毁在堆上创建的对象
 140:      //关于智能指针以及对象工厂的原理及使用,另外进行演示
 141:      registration->Delete();
 142:      optimizer->Delete();
 143:      metric->Delete();
 144:      observer->Delete();
 145:   
 146:      return EXIT_SUCCESS;
 147:  }

 

//根据程序中设置的初值,执行过程如下:

StartOptimization:   InitialPosition  =   9   CurrentIteration =   0   MetricValue =  91

MyIterationEvent:    CurrentPosition  =  14   CurrentIteration =   1   MetricValue =  86
MyIterationEvent:    CurrentPosition  =  19   CurrentIteration =   2   MetricValue =  81
MyIterationEvent:    CurrentPosition  =  24   CurrentIteration =   3   MetricValue =  76
MyIterationEvent:    CurrentPosition  =  29   CurrentIteration =   4   MetricValue =  71
MyIterationEvent:    CurrentPosition  =  34   CurrentIteration =   5   MetricValue =  66
MyIterationEvent:    CurrentPosition  =  39   CurrentIteration =   6   MetricValue =  61
MyIterationEvent:    CurrentPosition  =  44   CurrentIteration =   7   MetricValue =  56
MyIterationEvent:    CurrentPosition  =  49   CurrentIteration =   8   MetricValue =  51
MyIterationEvent:    CurrentPosition  =  54   CurrentIteration =   9   MetricValue =  46
MyIterationEvent:    CurrentPosition  =  59   CurrentIteration =  10   MetricValue =  41
MyIterationEvent:    CurrentPosition  =  64   CurrentIteration =  11   MetricValue =  36
MyIterationEvent:    CurrentPosition  =  69   CurrentIteration =  12   MetricValue =  31
MyIterationEvent:    CurrentPosition  =  74   CurrentIteration =  13   MetricValue =  26
MyIterationEvent:    CurrentPosition  =  79   CurrentIteration =  14   MetricValue =  21
MyIterationEvent:    CurrentPosition  =  84   CurrentIteration =  15   MetricValue =  16
MyIterationEvent:    CurrentPosition  =  89   CurrentIteration =  16   MetricValue =  11
MyIterationEvent:    CurrentPosition  =  94   CurrentIteration =  17   MetricValue =   6
MyIterationEvent:    CurrentPosition  =  99   CurrentIteration =  18   MetricValue =   1
MyIterationEvent:    CurrentPosition  = 104   CurrentIteration =  19   MetricValue =  -4
MyIterationEvent:    CurrentPosition  = 103   CurrentIteration =  20   MetricValue =  -3
MyIterationEvent:    CurrentPosition  = 102   CurrentIteration =  21   MetricValue =  -2
MyIterationEvent:    CurrentPosition  = 101   CurrentIteration =  22   MetricValue =  -1
MyIterationEvent:    CurrentPosition  = 100   CurrentIteration =  23   MetricValue =   0

StopOptimization......  End.

|----------------------------------------
Result =
   LastPosition   = 100
   Iterations      = 24
   Metric value  = 0
|----------------------------------------

Print some information about registrationMethod:
RTTI typeinfo:   class MyRegistrationMethod
    Observers:
        none
        Metric:    class MyCostFunction *
        Optimizer: class MyOptimizer *

Next Print some information about the optimizer:
RTTI typeinfo:   class MyConcreteOptimizer
    Observers:
        MyStartEvent(MyCommand)
        MyIterationEvent(MyCommand)
        MyEndEvent(MyCommand)

        SomeParameters: 
        CostFunction           =   MySimpleMetric
        InitialPosition           =   9
        CurrentPosition       =   100
        NumberOfIteration  =   50
        CurrentMetricValue  =   0
        StepLength             =   5

可以看到,初值为 9,步长为 5 的,即如果测度值为正,则 CurrentPosition += 5;否则,CurrentPosition –= 1;则迭代了总共 24 次,最终值达到了 100,当值达到 100 时,测度值达到最佳值 0。

最后还测试了 Print() 函数,这个很容易看懂。

你可能感兴趣的:(框架,优化,OS,command,delete,Parameters)