]> Creatis software - clitk.git/blob - itk/itkFlexibleBinaryFunctorImageFilter.txx
Change some SetInputData into SetInputConnection to be consistent with algorithm...
[clitk.git] / itk / itkFlexibleBinaryFunctorImageFilter.txx
1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkFlexibleBinaryFunctorImageFilter.txx,v $
5   Language:  C++
6   Date:      $Date: 2008-10-07 17:31:02 $
7   Version:   $Revision: 1.40 $
8
9   Copyright (c) Insight Software Consortium. All rights reserved.
10   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11
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.
15
16 =========================================================================*/
17 #ifndef __itkFlexibleBinaryFunctorImageFilter_txx
18 #define __itkFlexibleBinaryFunctorImageFilter_txx
19
20 #include "itkFlexibleBinaryFunctorImageFilter.h"
21 #include "itkImageRegionIterator.h"
22 #include "itkImageRegionConstIterator.h"
23 #include "itkProgressReporter.h"
24
25 namespace itk
26 {
27
28 /**
29  * Constructor
30  */
31 template <class TInputImage1, class TInputImage2, 
32           class TOutputImage, class TFunction  >
33 FlexibleBinaryFunctorImageFilter<TInputImage1,TInputImage2,TOutputImage,TFunction>
34 ::FlexibleBinaryFunctorImageFilter()
35 {
36   this->SetNumberOfRequiredInputs( 1 );
37   this->SetInPlace(false);
38 }
39
40
41 /**
42  * Connect one of the operands for pixel-wise addition
43  */
44 template <class TInputImage1, class TInputImage2, 
45           class TOutputImage, class TFunction  >
46 void
47 FlexibleBinaryFunctorImageFilter<TInputImage1,TInputImage2,TOutputImage,TFunction>
48 ::SetInput1( const TInputImage1 * image1 ) 
49 {
50   // Process object is not const-correct so the const casting is required.
51   this->SetNthInput(0, const_cast<TInputImage1 *>( image1 ));
52 }
53
54
55 /**
56  * Connect one of the operands for pixel-wise addition
57  */
58 template <class TInputImage1, class TInputImage2, 
59           class TOutputImage, class TFunction  >
60 void
61 FlexibleBinaryFunctorImageFilter<TInputImage1,TInputImage2,TOutputImage,TFunction>
62 ::SetInput2( const TInputImage2 * image2 ) 
63 {
64   // Process object is not const-correct so the const casting is required.
65   //this->SetNthInput(1, const_cast<TInputImage2 *>( image2 ));
66   
67   m_Input2 = image2;
68 }
69
70 template <class TInputImage1, class TInputImage2, 
71           class TOutputImage, class TFunction  >
72 void
73 FlexibleBinaryFunctorImageFilter<TInputImage1,TInputImage2,TOutputImage,TFunction>
74 ::GenerateInputRequestedRegion()
75 {
76   Superclass::GenerateInputRequestedRegion();
77   
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() );
82   image2->Update();
83 }
84
85 template <class TInputImage1, class TInputImage2, 
86           class TOutputImage, class TFunction  >
87 void
88 FlexibleBinaryFunctorImageFilter<TInputImage1,TInputImage2,TOutputImage,TFunction>
89 ::GenerateOutputInformation() 
90 {
91   Superclass::GenerateOutputInformation() ;
92 }
93
94 /**
95  * ThreadedGenerateData Performs the pixel-wise addition
96  */
97 template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction  >
98 void
99 FlexibleBinaryFunctorImageFilter<TInputImage1, TInputImage2, TOutputImage, TFunction>
100 ::ThreadedGenerateData( const OutputImageRegionType &outputRegionForThread,
101 #if ITK_VERSION_MAJOR >= 4  
102                         itk::ThreadIdType threadId )
103 #else
104                         int threadId)
105 #endif
106 {
107   const unsigned int dim = Input1ImageType::ImageDimension;
108   
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);
117   
118   typename Input1ImageType::RegionType region2 = inputPtr2->GetLargestPossibleRegion();
119   
120   typename Input1ImageType::IndexType index1;
121   typename Input2ImageType::IndexType index2;
122   typename Input1ImageType::PointType point1;
123   typename Input2ImageType::PointType point2;
124
125   ImageRegionConstIterator<TInputImage1> inputIt1(inputPtr1, outputRegionForThread);
126   ImageRegionConstIterator<TInputImage2> inputIt2(inputPtr2, region2);
127
128   ImageRegionIterator<TOutputImage> outputIt(outputPtr, outputRegionForThread);
129
130   ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
131   
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();
140
141   while( !inputIt1.IsAtEnd() ) {
142     if (region2.IsInside(index2)) {
143       outputIt.Set( m_Functor( inputIt1.Get(), inputIt2.Get() ) );
144     }
145     else {
146       outputIt.Set(inputIt1.Get());
147     }
148     
149     ++inputIt1;
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);
156     ++outputIt;
157     
158     progress.CompletedPixel(); // potential exception thrown here
159   }
160 }
161
162 } // end namespace itk
163
164 #endif