ITK的数据流采用如图1所示流水线(pipeline)作业方式。遵循此方式,所处理的数据来龙去脉清晰明了。在图1中,数据流左边的ImageFile代表待处理的图像文件,而右边ImageFile则代表处理后的图像文件。ImageFileReade:将存贮图像文件读人到内存,形成Image,再调用所希望处理的Fileter算法(比如滤波、分割、配准等具体算法),将对读人的图像数据进行处理。最后,ImageFileWriter将处理的图像数据结果保存,或输人给图形显示系统(如VTK),进行数据可视化。

VTK是C++语言开发的、公开源码的、面向对象的数据可视化软件开发包,并不单纯用于医学图像数据的可视化。VTK支持跨平台的编译,可以应用于Windows,Linux等系统。VTK支持包括数量、向量、张量、结构和测定体积等方法一系列可视化算法,VTK还支持包括建模。VTK的数据流同样采用流水线作业方式,如图2所示。

vtkSource为整个可视化流的开始,比如读取、生成数据等。vtkFilte对输入源数据进行各种处理,与ITK的Fileter类似。原始数据经过各种Filte:的处理后,再由vtkMappe:转换(或映射)成可供其它算法模块直接使用的数据形式,比如为几何数据。vtkActor类用来描述绘制场景中一个实体,即绘制场景的某个角色(Actor)。通过SetMapper()方法,可以将几何数据的属性传递给Actor,再由vtkRenderer类将处理后的数据结果显示出来。
由于ITK和VTK的数据流都是采用流水线作业形式,比较方便地利用类库本身提供的类型转换类来实现,如图3所示。通过ITKtoVTKImageFilter类操作将ITK和VTK的图像数据连接了起来,VTK负责图像数据的显示,而ITK负责图像的处理,其中VTK的Image Viewe:是一个很方便实现的图像显示类,它在内部管理着vtkImageWindow, vtkRenderer, vtkActor2D和vtkImageMapper等图象类,实现图像查看、显示和可视化功能。

**下面具体解释下ITK对象到VTK对象的两种转换方式:**
**第一种**方式是使用**itkImageToVTKImageFilter**类
通过例子来说明:
#include "itkImage.h" #include "itkImageFileReader.h" #include "itkImageToVTKImageFilter.h" #include "vtkImageViewer.h" #include "vtkRenderWindowInteractor.h" int main( int argc, char **argv ) { typedef itk::Image< unsigned short, 2 > ImageType; typedef itk::ImageFileReader<ImageType> ReaderType; typedef itk::ImageToVTKImageFilter< ImageType> FilterType; ReaderType::Pointer reader = ReaderType::New(); FilterType::Pointer connector = FilterType::New(); reader->SetFileName( "d:\\1.png"); connector->SetInput( reader->GetOutput() ); vtkImageViewer * viewer = vtkImageViewer::New(); vtkRenderWindowInteractor * renderWindowInteractor = vtkRenderWindowInteractor::New(); viewer->SetupInteractor( renderWindowInteractor ); viewer->SetInput( connector->GetOutput() ); viewer->Render(); viewer->SetColorWindow( 255 ); viewer->SetColorLevel( 128 ); renderWindowInteractor->Start(); return 0; }
例子如下:
#include "itkCommand.h" #include "itkImage.h" #include "itkVTKImageExport.h" #include "itkVTKImageImport.h" #include "itkCurvatureFlowImageFilter.h" #include "itkCastImageFilter.h" #include "itkRGBPixel.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "vtkImageData.h" #include "vtkImageImport.h" #include "vtkImageExport.h" #include "vtkImageActor.h" #include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkInteractorStyleImage.h" #include "itkPNGImageIO.h" /** * This will be setup as a callback for a progress event on an ITK * filter. */ struct ProgressDisplay { ProgressDisplay(itk::ProcessObject* process): m_Process(process) {} void Display() { float progress = m_Process->GetProgress()*100.0; std::cout << "Progress " << progress << " percent." << std::endl; } itk::ProcessObject::Pointer m_Process; }; /** * This function will connect the given itk::VTKImageExport filter to * the given vtkImageImport filter. */ template <typename ITK_Exporter, typename VTK_Importer> void ConnectPipelines(ITK_Exporter exporter, VTK_Importer* importer) { importer->SetUpdateInformationCallback(exporter->GetUpdateInformationCallback()); importer->SetPipelineModifiedCallback(exporter->GetPipelineModifiedCallback()); importer->SetWholeExtentCallback(exporter->GetWholeExtentCallback()); importer->SetSpacingCallback(exporter->GetSpacingCallback()); importer->SetOriginCallback(exporter->GetOriginCallback()); importer->SetScalarTypeCallback(exporter->GetScalarTypeCallback()); importer->SetNumberOfComponentsCallback(exporter->GetNumberOfComponentsCallback()); importer->SetPropagateUpdateExtentCallback(exporter->GetPropagateUpdateExtentCallback()); importer->SetUpdateDataCallback(exporter->GetUpdateDataCallback()); importer->SetDataExtentCallback(exporter->GetDataExtentCallback()); importer->SetBufferPointerCallback(exporter->GetBufferPointerCallback()); importer->SetCallbackUserData(exporter->GetCallbackUserData()); } /** * This function will connect the given vtkImageExport filter to * the given itk::VTKImageImport filter. */ template <typename VTK_Exporter, typename ITK_Importer> void ConnectPipelines(VTK_Exporter* exporter, ITK_Importer importer) { importer->SetUpdateInformationCallback(exporter->GetUpdateInformationCallback()); importer->SetPipelineModifiedCallback(exporter->GetPipelineModifiedCallback()); importer->SetWholeExtentCallback(exporter->GetWholeExtentCallback()); importer->SetSpacingCallback(exporter->GetSpacingCallback()); importer->SetOriginCallback(exporter->GetOriginCallback()); importer->SetScalarTypeCallback(exporter->GetScalarTypeCallback()); importer->SetNumberOfComponentsCallback(exporter->GetNumberOfComponentsCallback()); importer->SetPropagateUpdateExtentCallback(exporter->GetPropagateUpdateExtentCallback()); importer->SetUpdateDataCallback(exporter->GetUpdateDataCallback()); importer->SetDataExtentCallback(exporter->GetDataExtentCallback()); importer->SetBufferPointerCallback(exporter->GetBufferPointerCallback()); importer->SetCallbackUserData(exporter->GetCallbackUserData()); } /** * This program implements an example connection between ITK and VTK * pipelines. The combined pipeline flows as follows: * * itkImageFileReader ==> itkVTKImageExport ==> * vtkImageImport ==> vtkImageActor * * The resulting vtkImageActor is displayed in a vtkRenderWindow. * Whenever the VTK pipeline executes, information is propagated * through the ITK pipeline. If the ITK pipeline is out of date, it * will re-execute and cause the VTK pipeline to update properly as * well. */ int main(int argc, char * argv [] ) { // Load a color image using ITK and display it with VTK try { typedef itk::RGBPixel< unsigned char > PixelType; typedef itk::Image< PixelType, 2 > ImageType; typedef itk::ImageFileReader< ImageType > ReaderType; ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName("d:\\1.png"); reader->Update(); typedef itk::VTKImageExport< ImageType > ExportFilterType; ExportFilterType::Pointer itkExporter = ExportFilterType::New(); itkExporter->SetInput( reader->GetOutput() ); // Create the vtkImageImport and connect it to the // itk::VTKImageExport instance. vtkImageImport* vtkImporter = vtkImageImport::New(); ConnectPipelines(itkExporter, vtkImporter); // Just for double checking export it from VTK back into ITK // and save it into a file. typedef itk::VTKImageImport< ImageType > ImportFilterType; ImportFilterType::Pointer itkImporter = ImportFilterType::New(); vtkImageExport* vtkExporter = vtkImageExport::New(); ConnectPipelines(vtkExporter, itkImporter); vtkExporter->SetInput( vtkImporter->GetOutput() ); typedef itk::ImageFileWriter< ImageType > WriterType; WriterType::Pointer itkWriter = WriterType::New(); itkWriter->SetInput( itkImporter->GetOutput() ); const char * filename = "d:\\2.png"; std::cout << "Writing file " << filename << std::endl; itkWriter->SetFileName( filename ); itkWriter->Update(); //------------------------------------------------------------------------ // VTK pipeline. //------------------------------------------------------------------------ // Create a vtkImageActor to help render the image. Connect it to // the vtkImporter instance. vtkImageActor* actor = vtkImageActor::New(); actor->SetInput(vtkImporter->GetOutput()); vtkInteractorStyleImage * interactorStyle = vtkInteractorStyleImage::New(); // Create a renderer, render window, and render window interactor to // display the results. vtkRenderer* renderer = vtkRenderer::New(); vtkRenderWindow* renWin = vtkRenderWindow::New(); vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New(); renWin->SetSize(500, 500); renWin->AddRenderer(renderer); iren->SetRenderWindow(renWin); iren->SetInteractorStyle( interactorStyle ); // Add the vtkImageActor to the renderer for display. renderer->AddActor(actor); renderer->SetBackground(0.4392, 0.5020, 0.5647); // Bring up the render window and begin interaction. renWin->Render(); iren->Start(); // Release all VTK components actor->Delete(); interactorStyle->Delete(); vtkImporter->Delete(); vtkExporter->Delete(); renWin->Delete(); renderer->Delete(); iren->Delete(); } catch( itk::ExceptionObject & e ) { std::cerr << "Exception catched !! " << e << std::endl; } return 0; }
【参考来源】:http://image.szpt.edu.cn/cn/Article_content.asp?id=311