1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ======================================================================-====*/
19 #ifndef CLITKEXTRACTBONESSFILTER_TXX
20 #define CLITKEXTRACTBONESSFILTER_TXX
23 #include "clitkImageCommon.h"
24 #include "clitkSetBackgroundImageFilter.h"
25 #include "clitkSegmentationFunctions.h"
26 #include "clitkAutoCropFilter.h"
29 #include "itkBinaryThresholdImageFilter.h"
30 #include "itkConnectedComponentImageFilter.h"
31 #include "itkRelabelComponentImageFilter.h"
32 #include "itkNeighborhoodConnectedImageFilter.h"
34 //--------------------------------------------------------------------
35 template <class TInputImageType, class TOutputImageType>
36 clitk::ExtractBonesFilter<TInputImageType, TOutputImageType>::
39 itk::ImageToImageFilter<TInputImageType, TOutputImageType>()
41 // Default global options
42 this->SetNumberOfRequiredInputs(1);
43 SetBackgroundValue(0); // Must be zero
44 SetForegroundValue(1);
46 SetMinimalComponentSize(100);
47 SetUpperThreshold1(1500);
48 SetLowerThreshold1(100);
49 SetFullConnectivity(false);
51 SetUpperThreshold2(1500);
52 SetLowerThreshold2(10);
59 //--------------------------------------------------------------------
62 //--------------------------------------------------------------------
63 template <class TInputImageType, class TOutputImageType>
65 clitk::ExtractBonesFilter<TInputImageType, TOutputImageType>::
66 SetInput(const TInputImageType * image)
68 this->SetNthInput(0, const_cast<TInputImageType *>(image));
70 //--------------------------------------------------------------------
73 //--------------------------------------------------------------------
74 template <class TInputImageType, class TOutputImageType>
75 template<class ArgsInfoType>
77 clitk::ExtractBonesFilter<TInputImageType, TOutputImageType>::
78 SetArgsInfo(ArgsInfoType mArgsInfo)
80 SetVerboseOption_GGO(mArgsInfo);
81 SetVerboseStep_GGO(mArgsInfo);
82 SetWriteStep_GGO(mArgsInfo);
83 SetVerboseWarningOff_GGO(mArgsInfo);
85 SetMinimalComponentSize_GGO(mArgsInfo);
86 SetUpperThreshold1_GGO(mArgsInfo);
87 SetLowerThreshold1_GGO(mArgsInfo);
88 SetFullConnectivity_GGO(mArgsInfo);
90 SetUpperThreshold2_GGO(mArgsInfo);
91 SetLowerThreshold2_GGO(mArgsInfo);
92 SetRadius2_GGO(mArgsInfo);
93 SetSampleRate2_GGO(mArgsInfo);
94 SetAutoCrop_GGO(mArgsInfo);
96 //--------------------------------------------------------------------
99 //--------------------------------------------------------------------
100 template <class TInputImageType, class TOutputImageType>
102 clitk::ExtractBonesFilter<TInputImageType, TOutputImageType>::
103 GenerateOutputInformation() {
104 // Get input pointers
105 InputImagePointer input = dynamic_cast<TInputImageType*>(itk::ProcessObject::GetInput(0));
106 // InputImagePointer input = dynamic_cast<TInputImageType*>(itk::ProcessObject::GetInput(0));
107 Superclass::GenerateOutputInformation();
108 OutputImagePointer outputImage = this->GetOutput(0);
109 outputImage->SetRegions(input->GetLargestPossibleRegion());
112 typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> InputBinarizeFilterType;
113 typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> BinarizeFilterType;
114 typedef itk::ConnectedComponentImageFilter<InternalImageType, InternalImageType> ConnectFilterType;
115 typedef itk::RelabelComponentImageFilter<InternalImageType, InternalImageType> RelabelFilterType;
116 typedef clitk::SetBackgroundImageFilter<InternalImageType,InternalImageType, InternalImageType> SetBackgroundFilterType;
117 typedef itk::CastImageFilter<InternalImageType,OutputImageType> CastImageFilterType;
118 typedef itk::ImageFileWriter<OutputImageType> WriterType;
120 //--------------------------------------------------------------------
121 //--------------------------------------------------------------------
122 StartNewStep("Initial Labeling");
124 typename InternalImageType::Pointer firstLabelImage;
126 //---------------------------------
127 // Binarize the image
128 //---------------------------------
129 typename InputBinarizeFilterType::Pointer binarizeFilter=InputBinarizeFilterType::New();
130 binarizeFilter->SetInput(input);
131 binarizeFilter->SetLowerThreshold(GetLowerThreshold1());
132 binarizeFilter->SetUpperThreshold(GetUpperThreshold1());
133 binarizeFilter->SetInsideValue(this->GetForegroundValue());
134 binarizeFilter->SetOutsideValue(this->GetBackgroundValue());
136 //---------------------------------
137 // Label the connected components
138 //---------------------------------
139 typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
140 connectFilter->SetInput(binarizeFilter->GetOutput());
141 connectFilter->SetBackgroundValue(this->GetBackgroundValue());
142 connectFilter->SetFullyConnected(GetFullConnectivity());
144 //---------------------------------
145 // Sort the labels according to size
146 //---------------------------------
147 typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New();
148 relabelFilter->SetInput(connectFilter->GetOutput());
149 relabelFilter->SetMinimumObjectSize(GetMinimalComponentSize());
151 //---------------------------------
153 //---------------------------------
154 typename BinarizeFilterType::Pointer binarizeFilter2=BinarizeFilterType::New();
155 binarizeFilter2->SetInput(relabelFilter->GetOutput());
156 binarizeFilter2->SetLowerThreshold(1);
157 binarizeFilter2->SetUpperThreshold(1);
158 binarizeFilter2->SetInsideValue(this->GetForegroundValue());
159 binarizeFilter2->SetOutsideValue(this->GetBackgroundValue());
160 binarizeFilter2->Update();
162 firstLabelImage = binarizeFilter2->GetOutput();
164 //--------------------------------------------------------------------
165 //--------------------------------------------------------------------
166 StartNewStep("Neighborhood connected filter");
167 typename InternalImageType::Pointer secondLabelImage;
169 //---------------------------------
170 //Neighborhood connected RG
171 //---------------------------------
172 typedef itk::NeighborhoodConnectedImageFilter<InputImageType, InternalImageType>
173 NeighborhoodConnectedImageFilterType;
174 typename NeighborhoodConnectedImageFilterType::Pointer neighborhoodConnectedImageFilter=
175 NeighborhoodConnectedImageFilterType::New();
178 neighborhoodConnectedImageFilter->SetLower(GetLowerThreshold2());
179 neighborhoodConnectedImageFilter->SetUpper(GetUpperThreshold2());
180 neighborhoodConnectedImageFilter->SetReplaceValue(this->GetForegroundValue());
181 neighborhoodConnectedImageFilter->SetRadius(GetRadius2());
182 neighborhoodConnectedImageFilter->SetInput(input);
184 // Seeds from label image
185 typedef itk::ImageRegionIteratorWithIndex<InternalImageType> IteratorType;
186 IteratorType it(firstLabelImage, firstLabelImage->GetLargestPossibleRegion());
187 typename InputImageType::IndexType index;
188 unsigned int counter=0;
189 while (!it.IsAtEnd())
191 if (it.Get()==this->GetForegroundValue())
195 neighborhoodConnectedImageFilter->AddSeed(index);
198 while (!it.IsAtEnd() && i< (unsigned int) GetSampleRate2())
207 neighborhoodConnectedImageFilter->Update();
208 secondLabelImage = neighborhoodConnectedImageFilter->GetOutput();
210 //--------------------------------------------------------------------
211 //--------------------------------------------------------------------
212 StartNewStep("Combine de images");
213 typedef clitk::SetBackgroundImageFilter<InternalImageType, InternalImageType, InternalImageType>
214 SetBackgroundImageFilterType;
215 typename SetBackgroundImageFilterType::Pointer setBackgroundFilter=SetBackgroundImageFilterType::New();
216 setBackgroundFilter->SetInput(firstLabelImage);
217 setBackgroundFilter->SetInput2(secondLabelImage);
218 setBackgroundFilter->SetMaskValue(this->GetForegroundValue());
219 setBackgroundFilter->SetOutsideValue(this->GetForegroundValue());
220 setBackgroundFilter->Update();
222 output = setBackgroundFilter->GetOutput();
224 //--------------------------------------------------------------------
225 //--------------------------------------------------------------------
228 StartNewStep("AutoCrop");
229 typedef clitk::AutoCropFilter<InternalImageType> CropFilterType;
230 typename CropFilterType::Pointer cropFilter = CropFilterType::New();
231 cropFilter->SetInput(output);
232 cropFilter->SetBackgroundValue(GetBackgroundValue());
233 cropFilter->Update();
234 output = cropFilter->GetOutput();
235 StopCurrentStep<InternalImageType>(output);
236 outputImage->SetRegions(output->GetLargestPossibleRegion());
240 //--------------------------------------------------------------------
243 //--------------------------------------------------------------------
244 template <class TInputImageType, class TOutputImageType>
246 clitk::ExtractBonesFilter<TInputImageType, TOutputImageType>::
249 //--------------------------------------------------------------------
250 //--------------------------------------------------------------------
252 typedef itk::CastImageFilter<InternalImageType, OutputImageType> CastImageFilterType;
253 typename CastImageFilterType::Pointer caster= CastImageFilterType::New();
254 caster->SetInput(output);
256 //this->SetNthOutput(0, caster->GetOutput());
257 this->GraftOutput(caster->GetOutput());
260 //--------------------------------------------------------------------
263 #endif //#define CLITKBOOLEANOPERATORLABELIMAGEFILTER_TXX