Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
itkNeighborhoodFunctorImageFilter.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #ifndef itkNeighborhoodFunctorImageFilter_cpp
14 #define itkNeighborhoodFunctorImageFilter_cpp
15 
17 #include "itkNeighborhoodAlgorithm.h"
18 #include <itkVectorImageToImageAdaptor.h>
19 
20 namespace itk
21 {
22 
23 template< typename TInputImage, typename TFeatureImageType , class FunctorType>
24 void
27 {
28  const TInputImage * input = this->GetInput(0);
29 
30  for(unsigned int i = 0 ; i < FunctorType::OutputCount; i ++)
31  {
32  typename FeatureImageType::Pointer output = TFeatureImageType::New();
33  output->SetRegions(input->GetLargestPossibleRegion());
34  output->SetSpacing(input->GetSpacing());
35  output->SetOrigin(input->GetOrigin());
36  output->SetDirection(input->GetDirection());
37  output->Allocate();
38  this->SetNthOutput( i, output.GetPointer() );
39  }
40 
41  if(m_MaskImage.IsNull())
42  {
43  m_MaskImage = MaskImageType::New();
44  m_MaskImage->SetRegions(input->GetLargestPossibleRegion());
45  m_MaskImage->Allocate();
46  m_MaskImage->FillBuffer(1);
47  }
48 }
49 
50 template< typename TInputImage, typename TFeatureImageType , class FunctorType>
51 void
54 {
55 
56  // call the superclass' implementation of this method. this should
57  // copy the output requested region to the input requested region
58  Superclass::GenerateInputRequestedRegion();
59 
60  // get pointers to the input and output
61  auto inputPtr = const_cast<InputImageType *>(this->GetInput());
62 
63  if ( !inputPtr )
64  {
65  return;
66  }
67 
68  // get a copy of the input requested region (should equal the output
69  // requested region)
70  typename TInputImage::RegionType inputRequestedRegion;
71  inputRequestedRegion = inputPtr->GetRequestedRegion();
72 
73  // pad the input requested region by the operator radius
74  inputRequestedRegion.PadByRadius( m_Size );
75 
76  // crop the input requested region at the input's largest possible region
77  if ( inputRequestedRegion.Crop( inputPtr->GetLargestPossibleRegion() ) )
78  {
79  inputPtr->SetRequestedRegion(inputRequestedRegion);
80  return;
81  }
82  else
83  {
84  // Couldn't crop the region (requested region is outside the largest
85  // possible region). Throw an exception.
86 
87  // store what we tried to request (prior to trying to crop)
88  inputPtr->SetRequestedRegion(inputRequestedRegion);
89 
90  // build an exception
91  InvalidRequestedRegionError e(__FILE__, __LINE__);
92  e.SetLocation(ITK_LOCATION);
93  e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
94  e.SetDataObject(inputPtr);
95  throw e;
96  }
97 }
98 
99 template< typename TInputImage, typename TFeatureImageType, class FunctorType >
100 void
102 ::ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread,
103  ThreadIdType /*threadId*/)
104 {
105 
106 
107  typedef NeighborhoodAlgorithm::ImageBoundaryFacesCalculator< InputImageType > BFC;
108  typedef typename BFC::FaceListType FaceListType;
109  BFC faceCalculator;
110  FaceListType faceList;
111 
112  // Allocate output
113  const InputImageType *input = this->GetInput();
114 
115  // Break the input into a series of regions. The first region is free
116  // of boundary conditions, the rest with boundary conditions. Note,
117  // we pass in the input image and the OUTPUT requested region. We are
118  // only concerned with centering the neighborhood operator at the
119  // pixels that correspond to output pixels.
120  faceList = faceCalculator( input, outputRegionForThread, m_Size );
121 
122  typename FaceListType::iterator fit;
123  ImageRegionConstIterator< MaskImageType > mit;
124 
125  // Process non-boundary region and each of the boundary faces.
126  // These are N-d regions which border the edge of the buffer.
127  ConstNeighborhoodIterator< InputImageType > bit;
128 // for ( fit = faceList.begin(); fit != faceList.end(); ++fit )
129 // {
130  bit = ConstNeighborhoodIterator< InputImageType >(m_Size, input, outputRegionForThread);
131 
132  mit = ImageRegionConstIterator< MaskImageType >(m_MaskImage, outputRegionForThread);
133 
134  std::vector<ImageRegionIterator< FeatureImageType > > featureImageIterators;
135 
136  for(unsigned int i = 0; i < FunctorType::OutputCount; i++)
137  {
138  featureImageIterators.push_back(ImageRegionIterator< FeatureImageType >(this->GetOutput(i), outputRegionForThread));
139  featureImageIterators[i].GoToBegin();
140  }
141 
142  mit.GoToBegin();
143  bit.GoToBegin();
144 
145  while ( !bit.IsAtEnd() || !mit.IsAtEnd() )
146  {
147  if(mit.Value() != 0)
148  {
149  //bit.GetNeighborhood().Print(std::cout);
150  typename FunctorType::OutputVectorType features = ( m_Functor( bit ) );
151 
152  for(unsigned int i = 0 ; i < FunctorType::OutputCount; i++)
153  featureImageIterators[i].Set(features[i]);
154  }
155 
156  for(unsigned int i = 0 ; i < FunctorType::OutputCount; i++)
157  ++featureImageIterators[i];
158  ++bit;
159  ++mit;
160  }
161 // }
162 
163  std::cout << "Thread done!" << std::endl;
164 }
165 } // end namespace itk
166 
167 
168 #endif //itkNeighborhoodFunctorImageFilter_cpp
Superclass::OutputImageRegionType OutputImageRegionType
void ThreadedGenerateData(const OutputImageRegionType &outputRegionForThread, ThreadIdType threadId) override
const char features[]