]> Creatis software - clitk.git/blob - itk/clitkBooleanOperatorLabelImageFilter.txx
Remove vcl_math calls
[clitk.git] / itk / clitkBooleanOperatorLabelImageFilter.txx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to: 
5   - University of LYON              http://www.universite-lyon.fr/
6   - Léon Bérard cancer center       http://www.centreleonberard.fr
7   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
8
9   This software is distributed WITHOUT ANY WARRANTY; without even
10   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11   PURPOSE.  See the copyright notices for more information.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17   ===========================================================================**/
18
19 #ifndef CLITKBOOLEANOPERATORLABELIMAGEFILTER_TXX
20 #define CLITKBOOLEANOPERATORLABELIMAGEFILTER_TXX
21
22 #include "clitkCommon.h"
23 #include "clitkBooleanOperatorLabelImageFilter.h"
24 #include "clitkBoundingBoxUtils.h"
25
26 namespace clitk {
27
28   //--------------------------------------------------------------------
29   template <class TInputImage1, class TInputImage2, class TOutputImage>
30   BooleanOperatorLabelImageFilter<TInputImage1, TInputImage2, TOutputImage>::
31   BooleanOperatorLabelImageFilter():itk::InPlaceImageFilter<TInputImage1, TOutputImage>() {
32     this->SetNumberOfRequiredInputs( 2 );
33     this->InPlaceOn();    
34     mBackgroundValue1 = 0;
35     mBackgroundValue2 = 0;
36     mBackgroundValue  = 0;
37     mForegroundValue = 1;
38     m_OperationType = AndNot;
39   }
40   //--------------------------------------------------------------------
41
42
43   //--------------------------------------------------------------------
44   template <class TInputImage1, class TInputImage2, class TOutputImage>
45   void 
46   BooleanOperatorLabelImageFilter<TInputImage1, TInputImage2, TOutputImage>::
47   SetInput1(const TInputImage1 * image1) {
48     // Process object is not const-correct so the const casting is required.
49     this->SetNthInput(0, const_cast<TInputImage1 *>( image1 ));
50   }
51   //--------------------------------------------------------------------
52   
53
54   //--------------------------------------------------------------------
55   template <class TInputImage1, class TInputImage2, class TOutputImage>
56   void 
57   BooleanOperatorLabelImageFilter<TInputImage1, TInputImage2, TOutputImage>::  
58   SetBackgroundValue1(Input1ImagePixelType p) {
59     mBackgroundValue1 = p;
60   }
61   //--------------------------------------------------------------------
62
63
64   //--------------------------------------------------------------------
65   template <class TInputImage1, class TInputImage2, class TOutputImage>
66   void 
67   BooleanOperatorLabelImageFilter<TInputImage1, TInputImage2, TOutputImage>::  
68   SetBackgroundValue2(Input2ImagePixelType p) {
69     mBackgroundValue2 = p;
70   }
71   //--------------------------------------------------------------------
72
73
74   //--------------------------------------------------------------------
75   template <class TInputImage1, class TInputImage2, class TOutputImage>
76   void 
77   BooleanOperatorLabelImageFilter<TInputImage1, TInputImage2, TOutputImage>::  
78   SetBackgroundValue(OutputImagePixelType p) {
79     mBackgroundValue = p;
80   }
81   //--------------------------------------------------------------------
82
83
84   //--------------------------------------------------------------------
85   template <class TInputImage1, class TInputImage2, class TOutputImage>
86   void 
87   BooleanOperatorLabelImageFilter<TInputImage1, TInputImage2, TOutputImage>::  
88   SetForegroundValue(OutputImagePixelType p) {
89     mForegroundValue = p;
90   }
91   //--------------------------------------------------------------------
92
93
94   //--------------------------------------------------------------------
95   template <class TInputImage1, class TInputImage2, class TOutputImage>
96   void 
97   BooleanOperatorLabelImageFilter<TInputImage1, TInputImage2, TOutputImage>::
98   SetInput2(const TInputImage2 * image2) {
99     // Process object is not const-correct so the const casting is required.
100     this->SetNthInput(1, const_cast<TInputImage1 *>( image2 ));
101   }
102   //--------------------------------------------------------------------
103   
104
105   //--------------------------------------------------------------------
106   template <class TInputImage1, class TInputImage2, class TOutputImage>
107   void 
108   BooleanOperatorLabelImageFilter<TInputImage1, TInputImage2, TOutputImage>::
109   GenerateOutputInformation() { 
110
111     // Get input pointers
112     Input1ImagePointer input1 = dynamic_cast<TInputImage1*>(itk::ProcessObject::GetInput(0));
113     Input2ImagePointer input2 = dynamic_cast<TInputImage2*>(itk::ProcessObject::GetInput(1));
114      
115     // Check spacing
116     static const unsigned int Dim = Input1ImageType::ImageDimension;
117     for(unsigned int i=0; i<Dim; i++) {
118       if (input1->GetSpacing()[i] != input2->GetSpacing()[i]) {
119         clitkExceptionMacro("Input 1&2 must have the same spacing. " << std::endl
120                             << "\t input1 =  " << input1->GetSpacing() << std::endl
121                             << "\t input2 =  " << input2->GetSpacing() << std::endl);
122       }
123       // if (input1->GetLargestPossibleRegion().GetSize()[i] != input2->GetLargestPossibleRegion().GetSize()[i]) {
124 //         itkExceptionMacro(<< "Input 1&2 must have the same size. " << std::endl
125 //                           << "\t input1 =  " << input1->GetLargestPossibleRegion().GetSize() << std::endl
126 //                           << "\t input2 =  " << input2->GetLargestPossibleRegion().GetSize() << std::endl);
127 //       }
128     }
129
130     // Perform default implementation
131     Superclass::GenerateOutputInformation();
132
133     // Get output pointer
134     OutputImagePointer outputImage = this->GetOutput(0);
135
136     // If InPlace, do not create output
137     // DD(this->GetInPlace());
138     if (this->GetInPlace() && this->CanRunInPlace()) {
139       OutputImagePointer inputAsOutput
140         = dynamic_cast<TOutputImage *>(const_cast<TInputImage1 *>(this->GetInput()));
141       inputAsOutput->SetRequestedRegion(outputImage->GetLargestPossibleRegion());
142       inputAsOutput->SetBufferedRegion(outputImage->GetLargestPossibleRegion());  
143       // inputAsOutput->SetRegions(outputImage->GetLargestPossibleRegion());
144       this->GraftOutput( inputAsOutput );
145     }
146     else {
147       outputImage->SetRequestedRegion(outputImage->GetLargestPossibleRegion());
148       outputImage->SetBufferedRegion(outputImage->GetLargestPossibleRegion());  
149       outputImage->SetRegions(outputImage->GetLargestPossibleRegion());
150       outputImage->Allocate();
151       OutputImagePointer inputAsOutput
152         = dynamic_cast<TOutputImage *>(const_cast<TInputImage1 *>(this->GetInput()));
153       CopyValues<OutputImageType>(inputAsOutput, outputImage);
154     }
155
156     // Compute intersection bounding box (in physical coordinate) and regions (in pixel coordinate)
157     typedef itk::BoundingBox<unsigned long, Dim> BBType;
158     typename BBType::Pointer bbInput1 = BBType::New();    
159     ComputeBBFromImageRegion<Input1ImageType>(input1, input1->GetLargestPossibleRegion(), bbInput1);    
160     typename BBType::Pointer bbInput2 = BBType::New();    
161     ComputeBBFromImageRegion<Input2ImageType>(input2, input2->GetLargestPossibleRegion(), bbInput2);
162     typename BBType::Pointer bbOutput = BBType::New();    
163     ComputeBBFromImageRegion<OutputImageType>(outputImage, outputImage->GetLargestPossibleRegion(), bbOutput);
164     
165     typename BBType::Pointer bb = BBType::New();    
166     ComputeBBIntersection<Dim>(bb, bbInput1, bbInput2);
167     ComputeBBIntersection<Dim>(bb, bb, bbOutput);
168  
169     ComputeRegionFromBB<Input1ImageType>(input1, bb, input1Region);
170     ComputeRegionFromBB<Input2ImageType>(input2, bb, input2Region);
171     ComputeRegionFromBB<OutputImageType>(outputImage, bb, outputRegion);
172   }
173   //--------------------------------------------------------------------
174
175
176   //--------------------------------------------------------------------
177   template <class TInputImage1, class TInputImage2, class TOutputImage>
178   void 
179   BooleanOperatorLabelImageFilter<TInputImage1, TInputImage2, TOutputImage>::
180   GenerateInputRequestedRegion() {
181     // Call default
182     itk::InPlaceImageFilter<TInputImage1, TOutputImage>::GenerateInputRequestedRegion();
183     // Get input pointers and set requested region to common region
184     Input1ImagePointer input1 = dynamic_cast<TInputImage1*>(itk::ProcessObject::GetInput(0));
185     Input2ImagePointer input2 = dynamic_cast<TInputImage2*>(itk::ProcessObject::GetInput(1));
186     input1->SetRequestedRegion(input1Region);
187     input2->SetRequestedRegion(input2Region);  
188   }
189   //--------------------------------------------------------------------
190
191
192   //--------------------------------------------------------------------
193   template <class TInputImage1, class TInputImage2, class TOutputImage>
194   void 
195   BooleanOperatorLabelImageFilter<TInputImage1, TInputImage2, TOutputImage>::
196   GenerateData() {
197     // Get input pointers
198     Input1ImageConstPointer input1 = dynamic_cast<const TInputImage1*>(itk::ProcessObject::GetInput(0));
199     Input2ImageConstPointer input2 = dynamic_cast<const TInputImage2*>(itk::ProcessObject::GetInput(1));
200     
201     // Get output pointer
202     OutputImagePointer output = this->GetOutput(0);
203     
204     // Get Region iterators
205     itk::ImageRegionConstIterator<Input1ImageType> it1(input1, input1Region);
206     itk::ImageRegionConstIterator<Input2ImageType> it2(input2, input2Region);
207     itk::ImageRegionIterator<OutputImageType>      ot (output, outputRegion);
208     it1.GoToBegin();
209     it2.GoToBegin();
210     ot.GoToBegin();
211
212     switch (m_OperationType) {
213     case AndNot: LoopAndNot(it1, it2, ot);  break;
214     case And: LoopAnd(it1, it2, ot);  break;
215     case Or: LoopOr(it1, it2, ot);  break;
216     }
217   }
218   //--------------------------------------------------------------------
219   
220
221   //--------------------------------------------------------------------
222 #define LOOP_BEGIN(FUNCTION_NAME)                                       \
223   template <class TInputImage1, class TInputImage2, class TOutputImage> \
224   template <class Iter1, class Iter2>                                   \
225   void                                                                  \
226   BooleanOperatorLabelImageFilter<TInputImage1, TInputImage2, TOutputImage>:: \
227   FUNCTION_NAME(Iter1 it1, Iter1 it2, Iter2 ot) {                       \
228   while (!ot.IsAtEnd()) {
229   
230 #define LOOP_END ++it1; ++it2; ++ot; }}
231   //--------------------------------------------------------------------
232   
233
234   //--------------------------------------------------------------------
235   LOOP_BEGIN(LoopAndNot)
236   if ((it1.Get() != mBackgroundValue1) && (it2.Get() == mBackgroundValue2)) 
237     { ot.Set(mForegroundValue); }
238   else { ot.Set(mBackgroundValue); }
239   LOOP_END
240   //--------------------------------------------------------------------
241
242  
243   //--------------------------------------------------------------------
244   LOOP_BEGIN(LoopAnd)
245   if ((it1.Get() != mBackgroundValue1) && (it2.Get() != mBackgroundValue2)) 
246     { ot.Set(mForegroundValue); }
247   else { ot.Set(mBackgroundValue); }
248   LOOP_END
249   //--------------------------------------------------------------------
250
251  
252   //--------------------------------------------------------------------
253   LOOP_BEGIN(LoopOr)
254   if ((it1.Get() != mBackgroundValue1) || (it2.Get() != mBackgroundValue2)) 
255     { ot.Set(mForegroundValue); }
256   else { ot.Set(mBackgroundValue); }
257   LOOP_END
258   //--------------------------------------------------------------------
259
260  
261 }//end clitk
262  
263 #endif //#define CLITKBOOLEANOPERATORLABELIMAGEFILTER_TXX