剩下的几个头文件如下:
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: };
所有的头文件都已列出,后面先给出程序的简单类结构图,然后再给出头文件对应的代码实现,最后再进行一些简单的测试。