1 #ifndef clitkFillMaskGenericFilter_txx
2 #define clitkFillMaskGenericFilter_txx
4 /* =================================================
5 * @file clitkFillMaskGenericFilter.txx
11 ===================================================*/
17 //-------------------------------------------------------------------
18 // Update with the pixeltype
19 //-------------------------------------------------------------------
20 template <class PixelType>
22 FillMaskGenericFilter::UpdateWithPixelType()
25 const unsigned int Dimension=3;
26 typedef int InternalPixelType;
29 typedef itk::Image<PixelType, Dimension> InputImageType;
30 typedef itk::Image<InternalPixelType, Dimension> InternalImageType;
31 typedef itk::Image<PixelType, Dimension> OutputImageType;
34 typedef itk::ImageFileReader<InputImageType> InputReaderType;
35 typename InputReaderType::Pointer reader = InputReaderType::New();
36 reader->SetFileName( m_InputFileName);
38 typename InputImageType::Pointer input= reader->GetOutput();
40 // Read the directions over which to fill holes
41 std::vector<unsigned int> direction;
42 if (m_ArgsInfo.dir_given)
43 for ( unsigned int i=0;i<m_ArgsInfo.dir_given;i++)
44 direction.push_back(m_ArgsInfo.dir_arg[i]);
46 for ( unsigned int i=0;i<Dimension;i++)
47 direction.push_back(Dimension-i-1);
49 //----------------------------------------
50 // Cast to internal type
51 //----------------------------------------
52 typedef itk::CastImageFilter<InputImageType,InternalImageType> InputCastImageFilterType;
53 typename InputCastImageFilterType::Pointer inputCaster= InputCastImageFilterType::New();
54 inputCaster->SetInput(input);
55 inputCaster->Update();
57 //----------------------------------------
58 // Loop over directions
59 //----------------------------------------
60 typename InternalImageType::Pointer output=inputCaster->GetOutput();
61 for (unsigned int i=0; i<direction.size();i++)
64 //----------------------------------------
65 // Fill the holes of a mask in 2D
66 //----------------------------------------
67 if(m_Verbose) std::cout<<"Fill holes in the mask slice by slice in direction "<<direction[i]<<"..."<<std::endl;
69 // We define the region to be extracted.
70 typedef itk::Image<InternalPixelType, Dimension-1> ImageSliceType;
71 typedef itk::Image<InternalPixelType, Dimension-1> MaskSliceType;
72 typename InternalImageType::RegionType region3D= input->GetLargestPossibleRegion();
73 typename InternalImageType::RegionType::SizeType size3D= region3D.GetSize();
74 typename InternalImageType::RegionType::SizeType size2D=size3D;
75 size2D[direction[i]]=0;
76 typename InternalImageType::IndexType start2D;
78 typename InternalImageType::RegionType desiredRegion;
79 desiredRegion.SetSize( size2D );
80 desiredRegion.SetIndex( start2D );
83 typedef itk::ExtractImageFilter<InternalImageType, ImageSliceType> ExtractImageFilterType;
84 typedef itk::JoinSeriesImageFilter<ImageSliceType, InternalImageType> JoinSeriesFilterType;
85 typename JoinSeriesFilterType::Pointer joinFilter=JoinSeriesFilterType::New();
86 joinFilter->SetSpacing(input->GetSpacing()[direction[i]]);
88 //----------------------------------------
89 // Run over the sliceIndexs
90 // ----------------------------------------
91 for(unsigned int sliceIndex=0; sliceIndex <size3D[direction[i]]; sliceIndex++)
93 //----------------------------------------
94 // Extract mask sliceIndex
95 //----------------------------------------
96 typename ExtractImageFilterType::Pointer extractFilter=ExtractImageFilterType::New();
97 extractFilter->SetInput(output);
98 start2D[direction[i]]=sliceIndex;
99 desiredRegion.SetIndex( start2D );
100 extractFilter->SetExtractionRegion( desiredRegion );
101 extractFilter->Update( );
102 typename ImageSliceType::Pointer slice= extractFilter->GetOutput();
104 // Binarize the image (Before: OBJECT!=0, rest=0, After: object=1, rest=0 )
105 typedef itk::BinaryThresholdImageFilter<ImageSliceType,ImageSliceType> BinarizeFilterType;
106 typename BinarizeFilterType::Pointer binarizeFilter=BinarizeFilterType::New();
107 binarizeFilter->SetInput(slice);
108 binarizeFilter->SetUpperThreshold(0);
109 binarizeFilter->SetOutsideValue(0);
110 binarizeFilter->SetInsideValue(1);
111 // writeImage<ImageSliceType>(binarizeFilter->GetOutput(),"/home/jef/tmp/input.mhd");
113 // Perform connected labelling on the slice (body+air=0 )
114 typedef itk::ConnectedComponentImageFilter<ImageSliceType, ImageSliceType> ConnectFilterType;
115 typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
116 connectFilter->SetInput(binarizeFilter->GetOutput());
117 connectFilter->SetBackgroundValue(0);
118 connectFilter->SetFullyConnected(false);
119 //connectFilter->Update();
120 //writeImage<ImageSliceType>(connectFilter->GetOutput(),"/home/jef/tmp/connect.mhd");
123 typedef itk::RelabelComponentImageFilter<ImageSliceType, ImageSliceType> RelabelFilterType;
124 typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New();
125 relabelFilter->SetInput(connectFilter->GetOutput());
126 //relabelFilter->Update();
127 //writeImage<ImageSliceType>(relabelFilter->GetOutput(),"/home/jef/tmp/label.mhd");
130 typedef itk::ThresholdImageFilter<ImageSliceType> ThresholdFilterType;
131 typename ThresholdFilterType::Pointer thresholdFilter=ThresholdFilterType::New();
132 thresholdFilter->SetInput(relabelFilter->GetOutput());
133 thresholdFilter->SetUpper(1);
134 thresholdFilter->SetOutsideValue(0);
135 // thresholdFilter->Update();
136 // writeImage<ImageSliceType>(thresholdFilter->GetOutput(),"/home/jef/tmp/bin.mhd");
138 // Invert the labels (lung 1, rest 0)
139 typename BinarizeFilterType::Pointer switchFilter=BinarizeFilterType::New();
140 switchFilter->SetInput(thresholdFilter->GetOutput());
141 switchFilter->SetUpperThreshold(0);
142 switchFilter->SetOutsideValue(0);
143 switchFilter->SetInsideValue(1);
144 switchFilter->Update();
145 //writeImage<ImageSliceType>(switchFilter->GetOutput(),"/home/jef/tmp/inv_bin.mhd");
148 joinFilter->SetInput( sliceIndex, switchFilter->GetOutput());
151 // Join to a 3D image
152 if (m_Verbose) std::cout<<"Joining the slices..."<<std::endl;
153 joinFilter->Update();
155 // Permute the axes to reset to orientation
156 typedef itk::PermuteAxesImageFilter<InternalImageType> PermuteFilterType;
157 typename PermuteFilterType::Pointer permuteFilter=PermuteFilterType::New();
158 permuteFilter->SetInput(joinFilter->GetOutput());
159 typename PermuteFilterType::PermuteOrderArrayType order;
160 order[direction[i]]=2;
166 else if ( direction[i]==1)
171 else if (direction[i]==0)
176 permuteFilter->SetOrder(order);
177 permuteFilter->Update();
178 output =permuteFilter->GetOutput();
180 // Set the image direction to the input one
181 output->SetDirection(input->GetDirection());
182 output->SetOrigin(input->GetOrigin());
187 typedef itk::CastImageFilter<InternalImageType,OutputImageType> OutputCastImageFilterType;
188 typename OutputCastImageFilterType::Pointer outputCaster =OutputCastImageFilterType::New();
189 outputCaster->SetInput(output);
192 typedef itk::ImageFileWriter<OutputImageType> WriterType;
193 typename WriterType::Pointer writer = WriterType::New();
194 writer->SetFileName(m_ArgsInfo.output_arg);
195 writer->SetInput(outputCaster->GetOutput());
201 #endif //#define clitkFillMaskGenericFilter_txx