1 /*============================================================================
3 The Medical Imaging Interaction Toolkit (MITK)
5 Copyright (c) German Cancer Research Center (DKFZ)
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
11 ============================================================================*/
13 #ifndef __itkMultiOutputNaryFunctorImageFilter_hxx
14 #define __itkMultiOutputNaryFunctorImageFilter_hxx
16 #include "itkMultiOutputNaryFunctorImageFilter.h"
17 #include "itkImageRegionIterator.h"
18 #include "itkProgressReporter.h"
25 template< class TInputImage, class TOutputImage, class TFunction, class TMaskImage >
26 MultiOutputNaryFunctorImageFilter< TInputImage, TOutputImage, TFunction, TMaskImage >
27 ::MultiOutputNaryFunctorImageFilter()
29 // This number will be incremented each time an image
30 // is added over the two minimum required
31 this->SetNumberOfRequiredInputs(1);
33 this->ActualizeOutputs();
36 template< class TInputImage, class TOutputImage, class TFunction, class TMaskImage >
38 MultiOutputNaryFunctorImageFilter< TInputImage, TOutputImage, TFunction, TMaskImage >
41 this->SetNumberOfRequiredOutputs(m_Functor.GetNumberOfOutputs());
43 for (typename Superclass::DataObjectPointerArraySizeType i = this->GetNumberOfIndexedOutputs(); i< m_Functor.GetNumberOfOutputs(); ++i)
45 this->SetNthOutput( i, this->MakeOutput(i) );
48 while(this->GetNumberOfIndexedOutputs() > m_Functor.GetNumberOfOutputs())
50 this->RemoveOutput(this->GetNumberOfIndexedOutputs()-1);
55 * ThreadedGenerateData Performs the pixel-wise addition
57 template< class TInputImage, class TOutputImage, class TFunction, class TMaskImage >
59 MultiOutputNaryFunctorImageFilter< TInputImage, TOutputImage, TFunction, TMaskImage >
60 ::ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread,
61 ThreadIdType threadId)
63 ProgressReporter progress( this, threadId,
64 outputRegionForThread.GetNumberOfPixels() );
66 const unsigned int numberOfInputImages =
67 static_cast< unsigned int >( this->GetNumberOfIndexedInputs() );
69 const unsigned int numberOfOutputImages =
70 static_cast< unsigned int >( this->GetNumberOfIndexedOutputs() );
72 typedef ImageRegionConstIterator< TInputImage > ImageRegionConstIteratorType;
73 std::vector< ImageRegionConstIteratorType * > inputItrVector;
74 inputItrVector.reserve(numberOfInputImages);
76 typedef ImageRegionIterator< TOutputImage > OutputImageRegionIteratorType;
77 std::vector< OutputImageRegionIteratorType * > outputItrVector;
78 outputItrVector.reserve(numberOfOutputImages);
80 //check if mask image is set and generate iterator if mask is valid
81 typedef ImageRegionConstIterator< TMaskImage > MaskImageRegionIteratorType;
82 MaskImageRegionIteratorType* pMaskIterator = nullptr;
84 if (m_Mask.IsNotNull())
86 if (!m_Mask->GetLargestPossibleRegion().IsInside(outputRegionForThread))
88 itkExceptionMacro("Mask of filter is set but does not cover region of thread. Mask region: "<< m_Mask->GetLargestPossibleRegion() <<"Thread region: "<<outputRegionForThread)
90 pMaskIterator = new MaskImageRegionIteratorType(m_Mask,outputRegionForThread);
93 // go through the inputs and add iterators for non-null inputs
94 for ( unsigned int i = 0; i < numberOfInputImages; ++i )
96 InputImagePointer inputPtr =
97 dynamic_cast< TInputImage * >( ProcessObject::GetInput(i) );
101 inputItrVector.push_back( new ImageRegionConstIteratorType(inputPtr, outputRegionForThread) );
106 // go through the outputs and add iterators for non-null outputs
107 for ( unsigned int i = 0; i < numberOfOutputImages; ++i )
109 OutputImagePointer outputPtr =
110 dynamic_cast< TOutputImage * >( ProcessObject::GetOutput(i) );
114 outputItrVector.push_back( new OutputImageRegionIteratorType(outputPtr, outputRegionForThread) );
118 typename std::vector< ImageRegionConstIteratorType * >::iterator regionInputIterators;
119 const typename std::vector< ImageRegionConstIteratorType * >::const_iterator regionInputItEnd =
120 inputItrVector.end();
122 typename std::vector< OutputImageRegionIteratorType * >::iterator regionOutputIterators;
123 const typename std::vector< OutputImageRegionIteratorType * >::const_iterator regionOutputItEnd =
124 outputItrVector.end();
126 const unsigned int numberOfValidInputImages = inputItrVector.size();
127 const unsigned int numberOfValidOutputImages = outputItrVector.size();
129 if ( (numberOfValidInputImages != 0) && ( numberOfValidOutputImages != 0))
134 while ( !(outputItrVector.front()->IsAtEnd()) )
136 typename NaryInputArrayType::iterator arrayInIt;
137 typename NaryOutputArrayType::iterator arrayOutIt;
138 NaryInputArrayType naryInputArray(numberOfValidInputImages);
139 NaryOutputArrayType naryOutputArray(numberOfValidOutputImages);
145 isValid = pMaskIterator->Get() > 0;
149 arrayInIt = naryInputArray.begin();
150 regionInputIterators = inputItrVector.begin();
152 typename ImageRegionConstIteratorType::IndexType currentIndex;
153 if(regionInputIterators != regionInputItEnd)
155 currentIndex = ( *regionInputIterators )->GetIndex();
158 while ( regionInputIterators != regionInputItEnd )
160 *arrayInIt++ = ( *regionInputIterators )->Get();
161 ++( *( *regionInputIterators ) );
162 ++regionInputIterators;
167 naryOutputArray = m_Functor(naryInputArray, currentIndex);
169 if (numberOfValidOutputImages != naryOutputArray.size())
171 itkExceptionMacro("Error. Number of valid output images do not equal number of outputs required by functor. Number of valid outputs: "<< numberOfValidOutputImages << "; needed output number:" << this->m_Functor.GetNumberOfOutputs());
176 for (typename NaryOutputArrayType::iterator pos = naryOutputArray.begin(); pos!= naryOutputArray.end(); ++pos)
182 arrayOutIt = naryOutputArray.begin();
183 regionOutputIterators = outputItrVector.begin();
184 while ( regionOutputIterators != regionOutputItEnd )
186 ( *regionOutputIterators )->Set(*arrayOutIt++);
187 ++( *( *regionOutputIterators ) );
188 ++regionOutputIterators;
191 progress.CompletedPixel();
196 // Free memory in case of exceptions
197 regionInputIterators = inputItrVector.begin();
198 while ( regionInputIterators != regionInputItEnd )
200 delete ( *regionInputIterators++ );
203 regionOutputIterators = outputItrVector.begin();
204 while ( regionOutputIterators != regionOutputItEnd )
206 delete ( *regionOutputIterators++ );
209 delete pMaskIterator;
214 // Free memory regulary
215 regionInputIterators = inputItrVector.begin();
216 while ( regionInputIterators != regionInputItEnd )
218 delete ( *regionInputIterators++ );
221 regionOutputIterators = outputItrVector.begin();
222 while ( regionOutputIterators != regionOutputItEnd )
224 delete ( *regionOutputIterators++ );
227 delete pMaskIterator;
229 } // end namespace itk