ANIMA  4.0
animaRemoveTouchingBorderFilter.hxx
Go to the documentation of this file.
1 #pragma once
2 
4 
5 namespace anima
6 {
7 
8 template<typename TInput, typename TMask, typename TOutput>
10 {
11  this->SetNthInput(0, const_cast<TInput*>(image));
12 }
13 
14 template<typename TInput, typename TMask, typename TOutput>
16 {
17  this->SetNthInput(1, const_cast<TMask*>(mask));
18 }
19 
20 
21 template<typename TInput, typename TMask, typename TOutput>
23 {
24  return static_cast< const TInput * >
25  ( this->itk::ProcessObject::GetInput(0) );
26 }
27 template<typename TInput, typename TMask, typename TOutput>
29 {
30  return static_cast< const TMask * >
31  ( this->itk::ProcessObject::GetInput(1) );
32 }
33 
34 
35 template<typename TInput, typename TMask, typename TOutput>
36 itk::DataObject::Pointer RemoveTouchingBorderFilter< TInput, TMask, TOutput >::MakeOutput(unsigned int idx)
37 {
38  itk::DataObject::Pointer output;
39 
40  switch ( idx )
41  {
42  case 0:
43  output = ( TOutput::New() ).GetPointer();
44  break;
45  case 1:
46  output = ( TOutput::New() ).GetPointer();
47  break;
48  default:
49  std::cerr << "No output " << idx << std::endl;
50  output = NULL;
51  break;
52  }
53  return output.GetPointer();
54 }
55 
56 template<typename TInput, typename TMask, typename TOutput>
58 {
59  return dynamic_cast< TOutput* >( this->itk::ProcessObject::GetOutput(0) );
60 }
61 
62 template<typename TInput, typename TMask, typename TOutput>
64 {
65  return dynamic_cast< TOutput* >( this->itk::ProcessObject::GetOutput(1) );
66 }
67 
68 template<typename TInput, typename TMask, typename TOutput>
69 void
72 {
73  if( m_OutputNonTouchingBorderFilename != "" )
74  {
75  std::cout << "Writing output non touching border image to: " << m_OutputNonTouchingBorderFilename << std::endl;
76  anima::writeImage<TOutput>(m_OutputNonTouchingBorderFilename, this->GetOutputNonTouchingBorder());
77  }
78 
79  if( m_OutputTouchingBorderFilename != "" )
80  {
81  std::cout << "Writing output touching border image to: " << m_OutputTouchingBorderFilename << std::endl;
82  anima::writeImage<TOutput>(m_OutputTouchingBorderFilename, this->GetOutputTouchingBorder());
83  }
84 }
85 
86 template<typename TInput, typename TMask, typename TOutput>
87 void
90 {
91  InputImagePointer InputImageSeg = InputImageType::New();
92  InputImageSeg->SetRegions(this->GetInputImageSeg()->GetLargestPossibleRegion());
93  InputImageSeg->CopyInformation(this->GetInputImageSeg());
94  InputImageSeg->Allocate();
95  InputImageSeg->FillBuffer(0);
96 
97  // Find labels overlaping mask border
98  InputIteratorType InputImageSegIt(InputImageSeg, InputImageSeg->GetLargestPossibleRegion() );
99  InputConstIteratorType maskSegIt(this->GetInputImageSeg(), this->GetInputImageSeg()->GetLargestPossibleRegion() );
100 
101  while(!maskSegIt.IsAtEnd())
102  {
103  InputImageSegIt.Set(maskSegIt.Get());
104 
105  ++maskSegIt;
106  ++InputImageSegIt;
107  }
108 
109  // --------------------------- Lesions
110  typename ConnectedComponentImageFilterType::Pointer connectedComponentImageFilter = ConnectedComponentImageFilterType::New();
111  typename LabelImageToLabelMapFilterType::Pointer labelImageToLabelMapFilter = LabelImageToLabelMapFilterType::New();
112  typename LabelImageToLabelMapFilterType2::Pointer labelImageToLabelMapFilter2 = LabelImageToLabelMapFilterType2::New();
113  typename LabelMapToLabelImageFilterType::Pointer labelMapToLabelImageFilter = LabelMapToLabelImageFilterType::New();
114  typename TOutputMap::Pointer labelMap = ITK_NULLPTR;
115  int originalNumberOfObject = 0;
116  bool connectivity = false;
117 
118  if( !m_LabeledImage )
119  {
120  // Create the labeled image of the input segmentation
121  connectedComponentImageFilter->SetInput( InputImageSeg );
122  connectedComponentImageFilter->SetFullyConnected( connectivity );
123  connectedComponentImageFilter->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() );
124  connectedComponentImageFilter->Update();
125 
126  labelImageToLabelMapFilter->SetInput( connectedComponentImageFilter->GetOutput() );
127  labelImageToLabelMapFilter->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
128  labelImageToLabelMapFilter->Update(); // The output of this filter is an itk::LabelMap, which contains itk::LabelObject's
129  originalNumberOfObject = labelImageToLabelMapFilter->GetOutput()->GetNumberOfLabelObjects() ;
130 
131  labelMap = labelImageToLabelMapFilter->GetOutput();
132  labelMap->DisconnectPipeline();
133  }
134  else
135  {
136  labelImageToLabelMapFilter2->SetInput( InputImageSeg );
137  labelImageToLabelMapFilter2->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
138  labelImageToLabelMapFilter2->Update(); // The output of this filter is an itk::LabelMap, which contains itk::LabelObject's
139  originalNumberOfObject = labelImageToLabelMapFilter2->GetOutput()->GetNumberOfLabelObjects() ;
140 
141  labelMap = labelImageToLabelMapFilter2->GetOutput();
142  labelMap->DisconnectPipeline();
143  }
144 
145  // Convert a LabelMap to a normal image with different values representing each region
146  labelMapToLabelImageFilter->SetInput( labelMap );
147  labelMapToLabelImageFilter->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
148  labelMapToLabelImageFilter->Update();
149 
150  // ------------------------------------- Mask bordure
151 
152  ImageIteratorTypeInt segLabelIt (labelMapToLabelImageFilter->GetOutput(), labelMapToLabelImageFilter->GetOutput()->GetLargestPossibleRegion() );
153 
154  std::vector<int> labelsToRemove;
155 
156  if(!m_NoContour)
157  {
158  // Get envelop of the mask
159  // Generate connected components
160  typename ConnectedComponentImageFilterType2::Pointer connectedComponentImageFilter2 = ConnectedComponentImageFilterType2::New();
161  connectedComponentImageFilter2->SetInput( this->GetMask() );
162  connectedComponentImageFilter2->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
163 
164  // Generate contours for each component
165  itk::LabelContourImageFilter<ImageTypeInt, ImageTypeInt>::Pointer labelContourImageFilter = itk::LabelContourImageFilter<ImageTypeInt, ImageTypeInt>::New();
166  labelContourImageFilter->SetInput( connectedComponentImageFilter2->GetOutput() );
167  labelContourImageFilter->SetFullyConnected(true);
168  labelContourImageFilter->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
169  labelContourImageFilter->SetBackgroundValue(0);
170  labelContourImageFilter->Update();
171 
172 
173  // Find labels overlaping mask border
174  ImageIteratorTypeInt maskContourIt (labelContourImageFilter->GetOutput(), labelContourImageFilter->GetOutput()->GetLargestPossibleRegion() );
175 
176  std::vector<int>::iterator it;
177  while(!maskContourIt.IsAtEnd())
178  {
179  if( maskContourIt.Get()!=0 && segLabelIt.Get()!=0 )
180  {
181  it = find (labelsToRemove.begin(), labelsToRemove.end(), segLabelIt.Get());
182  if (it == labelsToRemove.end())
183  {
184  labelsToRemove.push_back( segLabelIt.Get() );
185  m_labelsToRemove.push_back( segLabelIt.Get() );
186  }
187  }
188  ++maskContourIt;
189  ++segLabelIt;
190  }
191  }
192  else
193  {
194  // Find labels overlaping mask border
195  MaskConstIteratorType maskContourIt (this->GetMask(), this->GetMask()->GetLargestPossibleRegion() );
196 
197  std::vector<int>::iterator it;
198  while(!maskContourIt.IsAtEnd())
199  {
200  if( maskContourIt.Get()!=0 && segLabelIt.Get()!=0)
201  {
202  it = find (labelsToRemove.begin(), labelsToRemove.end(), segLabelIt.Get());
203  if (it == labelsToRemove.end())
204  {
205  labelsToRemove.push_back( segLabelIt.Get() );
206  m_labelsToRemove.push_back( segLabelIt.Get() );
207  }
208  }
209  ++maskContourIt;
210  ++segLabelIt;
211  }
212  }
213 
214 
215  // Remove all regions that were marked for removal.
216  for(unsigned int i = 0; i < labelsToRemove.size(); ++i)
217  {
218  labelMap->RemoveLabel(labelsToRemove[i]);
219  }
220 
221  // Convert a LabelMap to a normal image with different values representing each region
222  typename LabelMapToLabelImageFilterType::Pointer labelMapToLabelImageFilter2 = LabelMapToLabelImageFilterType::New();
223  labelMapToLabelImageFilter2->SetInput( labelMap );
224  labelMapToLabelImageFilter2->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
225  labelMapToLabelImageFilter2->Update();
226 
227  MaskConstIteratorType maskIt (this->GetMask(), this->GetMask()->GetLargestPossibleRegion() );
228  ImageIteratorTypeInt segIt (labelMapToLabelImageFilter2->GetOutput(), labelMapToLabelImageFilter2->GetOutput()->GetLargestPossibleRegion() );
229  maskSegIt.GoToBegin();
230 
231  OutputImagePointer output = this->GetOutputNonTouchingBorder();
232  output->SetRegions(this->GetInputImageSeg()->GetLargestPossibleRegion());
233  output->CopyInformation(this->GetInputImageSeg());
234  output->Allocate();
235  output->FillBuffer(0);
236 
237  OutputImagePointer output2 = this->GetOutputTouchingBorder();
238  output2->SetRegions(this->GetInputImageSeg()->GetLargestPossibleRegion());
239  output2->CopyInformation(this->GetInputImageSeg());
240  output2->Allocate();
241  output2->FillBuffer(0);
242 
243  OutputIteratorType outIt (output, output->GetLargestPossibleRegion() );
244  OutputIteratorType out2It (output2, output2->GetLargestPossibleRegion() );
245 
246  while(!maskIt.IsAtEnd())
247  {
248  if( segIt.Get()!=0)
249  {
250  outIt.Set(1);
251  }
252  if( (segIt.Get()==0) && (maskSegIt.Get()!=0))
253  {
254  out2It.Set(1);
255  }
256  ++maskIt;
257  ++segIt;
258  ++outIt;
259  ++out2It;
260  ++maskSegIt;
261  }
262 
263  if ( m_Verbose )
264  {
265  std::cout << " -- Rule to erase objects touching mask border: " << std::endl;
266  std::cout << " * Initial number of objects: " << originalNumberOfObject << std::endl;
267  std::cout << " * Number of rejected objects: " << labelsToRemove.size() << std::endl;
268  std::cout << " * Number of objects after clean: " << labelMap->GetNumberOfLabelObjects() << std::endl;
269  std::cout << std::endl;
270  }
271 
272 }
273 
274 
275 } //end of namespace anima
itk::ImageRegionIterator< OutputImageType > OutputIteratorType
itk::ImageRegionConstIterator< InputImageType > InputConstIteratorType
itk::ImageRegionIterator< ImageTypeInt > ImageIteratorTypeInt
itk::ImageRegionIterator< InputImageType > InputIteratorType
itk::DataObject::Pointer MakeOutput(unsigned int idx)
itk::ImageRegionConstIterator< MaskImageType > MaskConstIteratorType