ITK 实例2 连接门限对脑部MHA文件进行三维分割

发布时间 2023-08-16 14:51:51作者: 一杯清酒邀明月
  1 #include "itkConnectedThresholdImageFilter.h"//连接门限头文件
  2 #include "itkImage.h"
  3 #include "itkCastImageFilter.h"
  4 #include "itkCurvatureFlowImageFilter.h"
  5 #include "itkImageFileReader.h"
  6 #include "itkImageFileWriter.h"
  7 //图像中存在的噪声将大大降低滤波器生长大面积区域的能力。当面对噪声图像时,通常
  8 //是使用一个边缘保留平滑滤波器。
  9 int main( int argc, char *argv[])
 10 {
 11   /*if( argc < 7 )
 12     {
 13     std::cerr << "Missing Parameters " << std::endl;
 14     std::cerr << "Usage: " << argv[0];
 15     std::cerr << " inputImage  outputImage seedX seedY lowerThreshold upperThreshold" << std::endl;
 16     return EXIT_FAILURE;
 17     }*/
 18   /*我们基于一个特殊的像素类型和维来定义图像类型。由于平滑滤波器的需要,在这里我
 19   们使用浮点型数据定义像素*/
 20   typedef   float           InternalPixelType;
 21   const     unsigned int    Dimension = 3;
 22   typedef itk::Image< InternalPixelType, Dimension >  InternalImageType;
 23  
 24   typedef unsigned char                            OutputPixelType;
 25   typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
 26   typedef itk::CastImageFilter< InternalImageType, OutputImageType >
 27                                                    CastingFilterType;
 28   CastingFilterType::Pointer caster = CastingFilterType::New();
 29  
 30   //图像读取与图像写类型定义
 31   typedef  itk::ImageFileReader< InternalImageType > ReaderType;
 32   typedef  itk::ImageFileWriter<  OutputImageType  > WriterType;
 33   //图像读取与图像写对象实例化
 34   ReaderType::Pointer reader = ReaderType::New();
 35   WriterType::Pointer writer = WriterType::New();
 36  
 37   //reader->SetFileName( "BrainProtonDensitySlice.png" );
 38   reader->SetFileName("BrainProtonDensity3Slices.mha");
 39   writer->SetFileName( "ConnectedThreshold_baizhi.mha" );
 40  
 41   //使用图像类型作为模板参数来对平滑滤波器进行实例化
 42   typedef itk::CurvatureFlowImageFilter< InternalImageType, InternalImageType >
 43   CurvatureFlowImageFilterType;
 44   //调用 New() 方式来创建滤波器并将接指向 itk::SmartPointer
 45   //平滑滤波器实例化对象smoothing
 46   CurvatureFlowImageFilterType::Pointer smoothing =
 47                          CurvatureFlowImageFilterType::New();
 48   //声明区域生长滤波器的类型,本例中使用 ConnectedThresholdImageFilter
 49   typedef itk::ConnectedThresholdImageFilter< InternalImageType,
 50                                     InternalImageType > ConnectedFilterType;
 51   //使用 New( ) 方式构造这种类的一个滤波器
 52   //连接门限滤波器实例化对象connectedThreshold
 53   ConnectedFilterType::Pointer connectedThreshold = ConnectedFilterType::New();
 54   //读取图像进行平滑滤波
 55   smoothing->SetInput( reader->GetOutput() );
 56   //滤波后进行连接门限
 57   connectedThreshold->SetInput( smoothing->GetOutput() );
 58   /*由于只有一小部分图像文件格式支持浮点型数据类型,所以使
 59   用 cast filter 将浮点型数据类型转换成整型*/
 60   caster->SetInput( connectedThreshold->GetOutput() );
 61   //处理后输出数据到writer
 62   writer->SetInput( caster->GetOutput() );
 63   /*CurvatureFlowImageFilter(平滑滤波器)需要定义两个参数。下面是一个二维图像的常见值。
 64   当然它们也需要根据输入图像存在的噪声的数量进行适当的调整*/
 65   smoothing->SetNumberOfIterations( 5 );//越大滤波效果越好
 66   smoothing->SetTimeStep( 0.125 );
 67   /*ConnectedThresholdImageFilter(连通门限图像滤波)有两个主要的
 68   参数(lowerThreshold和upperThreshold)需要定义,
 69   它们分别是为了确定是否包含在区域中的亮度值而制定的标准的上门限和下门限。
 70   这两个值设定得太接近势必会降低区域生长的机动性,而设定得太远必将整个图像都卷入区域中*/
 71   const InternalPixelType lowerThreshold = atof( "150" );
 72   const InternalPixelType upperThreshold = atof( "180" );
 73  
 74   connectedThreshold->SetLower(  lowerThreshold  );
 75   connectedThreshold->SetUpper(  upperThreshold  );
 76   /*这个滤波器的输出是一个二值图像,这个二值图像除了分割出的区域外到处都是零值像
 77   素。区域中的亮度值是由 SetReplaceValue() 方式来选择的*/
 78   connectedThreshold->SetReplaceValue( 255 );
 79   
 80   InternalImageType::IndexType  index;
 81  
 82   /*这个算法的实例化需要用户提供一个种子点index。将这个点选在被分割的解剖学结构的典型
 83  区域是很便捷的。种子是以一种 itk::Index 的形式传递给 SetSeed() 方式的*/
 84   //白质种子点
 85   index[0] = atoi( "60" );
 86   index[1] = atoi( "116" );
 87   index[2] = atoi("2");
 88   connectedThreshold->SetSeed( index );
 89   /*writer 上的 Updata() 方法引发了管道的运行。通常在出现错误和抛出异议时, 从一个
 90   try / catch 模块调用 updata :*/
 91   try
 92     {
 93     writer->Update();
 94     }
 95   catch( itk::ExceptionObject & excep )
 96     {
 97     std::cerr << "Exception caught !" << std::endl;
 98     std::cerr << excep << std::endl;
 99     }
100     return EXIT_SUCCESS;
101 }