1. 程式人生 > >ITK學習筆記2(編譯介紹)

ITK學習筆記2(編譯介紹)

##1 include檔案和類定義

在 ITK 中類最大限度地定義在兩個檔案中:一個是.h 字尾的標頭檔案;另一個是執行檔案,非模板類時為.cxx 字尾,模板類為.txx 字尾。 除了類的標頭檔案外,下面介紹一些其他重要的標頭檔案。 itkMacro.h:在目錄 Code/Common 中定義了標準的系統 macros(例如 Set/Get、常數和其他引數)。 itkNumericTraits.h:在目錄 Code/Common 中定義了已知型別的數字化引數,例如它的最大值和最小值。 itkWin32Header.h:在目錄 Code/Common 中用來定義控制編譯過程的作業系統引數。

##面向物件

與標準的 C++類使用構造和解構函式所不同的是,ITK 中類的例項化是用靜態類 New()方式建立的。一般地,New( )方式通過Common/itkMacro.h 中的 macro itkNewMacro( )方式來宣告和實現。

記憶體管理:計數:引用計數通過一個 Register( )/Delete( )成員函式介面來實現。一個 ITK 物件的所有例項都是由引用它們的的物件使用一個 Register( )方式來呼叫的。Register( )方式增加例項的引用計 數。當 實 例引用消 失時 ,呼叫一 個 Delete( )方 式來減 少 例項的引 用計 數——這 和UnRegister( )方式是相同的。當引用計數為零時,例項將消失。

智慧指標:智慧指標的作用與常規指標一樣(例如支援操作符->和*),但當引用一個例項時執行 Register( )而當不再引用例項時用UnRegister( )。與 ITK 中大部分例項不同,智慧指標可以指向程式塊,當智慧指標生成的範圍關閉時會自動刪除。因此,在 ITK 中就應該儘量少用 Register( )和 Delete( )。

MyRegistrationFunction()`
{ <----- Start of scope`
// here an interpolator is created and associated to the
// SmartPointer "interp".
InterpolatorType::Pointer interp = InterpolatorType::New(); } <------ End of scope

在這個例子中,有一個引用計數為 1 的引用計數物件(使用 new( )方式)。賦值給物件指標的 interp 並未改變引用計數。在程式最後,interp 被釋放,當前物件 interpolator 的引用計數減少,當減少到零時,物件 interpolator 也被釋放。

錯誤處理

try
{
//...try executing some code here...
}
catch ( itk::ExceptionObject exp )
{
//...if an exception is thrown catch it here
}

資料表達: ITK 中有兩種基本的資料表示型別:影象和網格。這個功能是在類 Image 和 Mesh 中實現的,這兩個類都是itk::DataObject 的子類。 itk::Image 表示一個 n 維、規則的樣品資料。取樣方向平行於任一個座標軸,取樣起點、畫素間隔和每個方向上的樣品數量(如影象維數)是特定的。 ITK 中關於影象的一個重要概念是區域 regions,它是一個矩形的、連續的影象塊。區域用來指定影象中處理的部分,例如多執行緒或保留在記憶體中的部分。

  1. LargestPossibleRegion——全部影象。
  2. BufferedRegion——保留在記憶體中的影象部分。
  3. RequestedRegion——對影象操作時濾波器或其他類需要的部分。

網格類表示一個 n 維無結構的格子。網格類的拓撲佈局是由一套單元(cells)來表示的,單元(cells)是由一個型別和連通性列表來定義的;這個連通性列表依次涉及到點(points)。網格的幾何結構是通過 n 維的點(points)組合相關的單元插補函式來定義的。 網格以三個模板引數的形式來定義:1)和點、單元和單元邊界相關聯的一個畫素型別;2)點的維數(依次限制了單元的最大維);3)一個網格特徵模板引數,指定了用來儲存點、單元、邊界的容器和迭代器的型別。通過謹慎使用網格特徵,可以在允許表達複雜性、儲存器和速度之間的一個平衡的條件下,建立更適合於編輯或者更適合於只讀操作的網格。

資料處理管道: 資料處理管道連線了資料物件(如影象和網格)和過程物件。管道支援一個自動更新機制。該機制在當且僅當它的輸入或內在狀態改變時才會喚起一個濾波器來執行。另外,資料管道還支援 streaming,可以自動將資料分成許多小部分,對這些小部分進行逐一處理,並重新集合處理後的資料產生最終結果。通常使用 SetInput( )GetOutput( )方式連線資料物件和過程物件,方法程式碼如下:

typedef itk::Image<float,2> FloatImage2DType;
itk::RandomImageSource<FloatImage2DType>::Pointer random;
random = itk::RandomImageSource<FloatImage2DType>::New();
random->SetMin(0.0);
random->SetMax(1.0);
itk::ShrinkImageFilter<FloatImage2DType,FloatImage2DType>::Pointer shrink;
shrink = itk::ShrinkImageFilter<FloatImage2DType,FloatImage2DType>::New();
shrink->SetInput(random->GetOutput());*****
shrink->SetShrinkFactors(2);
itk::ImageFileWriter::Pointer<FloatImage2DType> writer;
writer = itk::ImageFileWriter::Pointer<FloatImage2DType>::New();
writer->SetInput (shrink->GetOutput());*****
writer->SetFileName( ‘‘test.raw’’ );
writer->Update();

在這個例子中,原始碼物件itk::RandomImageSourceitk::ShrinkImageFilter相連線,shrink 濾波器和 mapper itk::ImageFileWriter相連。當呼叫 Update( )方式時,資料處理管道就會按順序使用這些濾波器,並將最終結果儲存到檔案中。

空間物件:ITK 空間物件提供了一個介面,用來儲存物件的物理位置、幾何性質以及物件之間的關係,儲存是在獨立於用來表示這些物件的形式的情況下進行的。也就是說,由一個空間物件保持的內在表達可能是一個物件內在的列表、物件的表面網格、物件的內在點或表面的一個連續的或引數的表達等等。 空間物件框架提供的功能支援物件分割、配準、表面/立體檢視以及其他顯示和分析功能。空間物件框架擴張了對計算機檢視工具包很普遍的一個“scene graph”概念,因此也支援這些新函式功能。使用空間物件可以:

  1. 指定空間物件的父物件和子物件。在這種方式下,一個 liver 可以包含許多 vessels,而這些 vessels 可以用一個樹型結構來組織。
  2. 查詢一個物理點是否在一個物件或它的子物件中。
  3. 求出由一個物件或其子物件所指定的一個相關強度函式上某一物理點的值或派生值。
  4. 指定由一個父物件座標系轉換到一子物件座標系的轉換公式。
  5. 計算一個空間物件及其子物件的 bounding box。
  6. 查詢物件最初計算的 resolution。例如,你可以查詢一個用來生成 itk::BlobSpatialObject的一個特定例項的影象的 resolution (例如 voxel 空間)。

封裝: 封裝處理的結果是產生一系列可供解釋語言使用的共享庫,依照每種語言不同的句法要求 甚 至 可 以 直 接 轉 換 到 C++ 。 例 如 : 在 文 件 夾 Testing/Code/Algorithms 中 , 測 試itkCurvatureFlowTestTcl2.tcl 中有一段程式碼如下:

set cf [itkCurvatureFlowImageFilterF2F2_New]
$cf SetInput [$reader GetOutput]
$cf SetTimeStep 0.25
$cf SetNumberOfIterations 10C++中有同樣的程式碼如下:
itk::ImageFileReader<ImageType>::Pointer reader =
itk::ImageFileReader<ImageType>::New();
reader->SetFileName("cthead1.png");
itk::CurvatureFlowImageFilter<ImageType,ImageType>::Pointer cf =
itk::CurvatureFlowImageFilter<ImageType,ImageType>::New();
cf->SetInput(reader->GetOutput());
cf->SetTimeStep(0.25);
cf->SetNumberOfIterations(10);

通譯語言的優點就是不用像 C++語言那樣需要一個很長的編譯/連結週期。另外,它們通常都會附帶一套生成有用功能的工具包。