剩下的幾個頭文件如下:
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: };
所有的頭文件都已列出,後面先給出程序的簡單類結構圖,然後再給出頭文件對應的代碼實現,最後再進行一些簡單的測試。