1 /*=========================================================================
3 Program: Insight Segmentation & Registration Toolkit
4 Module: $RCSfile: itkFlexibleBinaryFunctorImageFilter.txx,v $
6 Date: $Date: 2008-10-07 17:31:02 $
7 Version: $Revision: 1.40 $
9 Copyright (c) Insight Software Consortium. All rights reserved.
10 See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #ifndef __itkFlexibleBinaryFunctorImageFilter_txx
18 #define __itkFlexibleBinaryFunctorImageFilter_txx
20 #include "itkFlexibleBinaryFunctorImageFilter.h"
21 #include "itkImageRegionIterator.h"
22 #include "itkImageRegionConstIterator.h"
23 #include "itkProgressReporter.h"
31 template <class TInputImage1, class TInputImage2,
32 class TOutputImage, class TFunction >
33 FlexibleBinaryFunctorImageFilter<TInputImage1,TInputImage2,TOutputImage,TFunction>
34 ::FlexibleBinaryFunctorImageFilter()
36 this->SetNumberOfRequiredInputs( 1 );
37 this->SetInPlace(false);
42 * Connect one of the operands for pixel-wise addition
44 template <class TInputImage1, class TInputImage2,
45 class TOutputImage, class TFunction >
47 FlexibleBinaryFunctorImageFilter<TInputImage1,TInputImage2,TOutputImage,TFunction>
48 ::SetInput1( const TInputImage1 * image1 )
50 // Process object is not const-correct so the const casting is required.
51 this->SetNthInput(0, const_cast<TInputImage1 *>( image1 ));
56 * Connect one of the operands for pixel-wise addition
58 template <class TInputImage1, class TInputImage2,
59 class TOutputImage, class TFunction >
61 FlexibleBinaryFunctorImageFilter<TInputImage1,TInputImage2,TOutputImage,TFunction>
62 ::SetInput2( const TInputImage2 * image2 )
64 // Process object is not const-correct so the const casting is required.
65 //this->SetNthInput(1, const_cast<TInputImage2 *>( image2 ));
70 template <class TInputImage1, class TInputImage2,
71 class TOutputImage, class TFunction >
73 FlexibleBinaryFunctorImageFilter<TInputImage1,TInputImage2,TOutputImage,TFunction>
74 ::GenerateInputRequestedRegion()
76 Superclass::GenerateInputRequestedRegion();
78 // Process object is not const-correct so the const casting is required.
79 // This "manual" update step is necessary because m_Input2 is not in the pipeline, since
80 // it's dimensions can be different from input 1.
81 TInputImage2* image2 = const_cast<TInputImage2 *>( m_Input2.GetPointer() );
85 template <class TInputImage1, class TInputImage2,
86 class TOutputImage, class TFunction >
88 FlexibleBinaryFunctorImageFilter<TInputImage1,TInputImage2,TOutputImage,TFunction>
89 ::GenerateOutputInformation()
91 Superclass::GenerateOutputInformation() ;
95 * ThreadedGenerateData Performs the pixel-wise addition
97 template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction >
99 FlexibleBinaryFunctorImageFilter<TInputImage1, TInputImage2, TOutputImage, TFunction>
100 ::ThreadedGenerateData( const OutputImageRegionType &outputRegionForThread,
101 #if ITK_VERSION_MAJOR >= 4
102 itk::ThreadIdType threadId )
107 const unsigned int dim = Input1ImageType::ImageDimension;
109 // We use dynamic_cast since inputs are stored as DataObjects. The
110 // ImageToImageFilter::GetInput(int) always returns a pointer to a
111 // TInputImage1 so it cannot be used for the second input.
112 Input1ImagePointer inputPtr1
113 = dynamic_cast<const TInputImage1*>(ProcessObject::GetInput(0));
114 Input2ImagePointer inputPtr2 = m_Input2;
115 /* = dynamic_cast<const TInputImage2*>(ProcessObject::GetInput(1));*/
116 OutputImagePointer outputPtr = this->GetOutput(0);
118 typename Input1ImageType::RegionType region2 = inputPtr2->GetLargestPossibleRegion();
120 typename Input1ImageType::IndexType index1;
121 typename Input2ImageType::IndexType index2;
122 typename Input1ImageType::PointType point1;
123 typename Input2ImageType::PointType point2;
125 ImageRegionConstIterator<TInputImage1> inputIt1(inputPtr1, outputRegionForThread);
126 ImageRegionConstIterator<TInputImage2> inputIt2(inputPtr2, region2);
128 ImageRegionIterator<TOutputImage> outputIt(outputPtr, outputRegionForThread);
130 ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
132 inputIt1.GoToBegin();
133 index1 = inputIt1.GetIndex();
134 inputPtr1->TransformIndexToPhysicalPoint(index1, point1);
135 for (unsigned int i = 0; i < dim; i++)
136 point2[i] = point1[i];
137 inputPtr2->TransformPhysicalPointToIndex(point2, index2);
138 inputIt2.SetIndex(index2);
139 outputIt.GoToBegin();
141 while( !inputIt1.IsAtEnd() ) {
142 if (region2.IsInside(index2)) {
143 outputIt.Set( m_Functor( inputIt1.Get(), inputIt2.Get() ) );
146 outputIt.Set(inputIt1.Get());
150 index1 = inputIt1.GetIndex();
151 inputPtr1->TransformIndexToPhysicalPoint(index1, point1);
152 for (unsigned int i = 0; i < dim; i++)
153 point2[i] = point1[i];
154 inputPtr2->TransformPhysicalPointToIndex(point2, index2);
155 inputIt2.SetIndex(index2);
158 progress.CompletedPixel(); // potential exception thrown here
162 } // end namespace itk