]> Creatis software - clitk.git/blob - itk/clitkBooleanOperatorLabelImageFilter.txx
add clitkExceptionMacro
[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://oncora1.lyon.fnclcc.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 "clitkSegmentationUtils.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     // DD(input1->GetLargestPossibleRegion());
158     // DD(input2->GetLargestPossibleRegion());
159     // DD(outputImage->GetLargestPossibleRegion());
160     typedef itk::BoundingBox<unsigned long, Dim> BBType;
161     typename BBType::Pointer bbInput1 = BBType::New();    
162     ComputeBBFromImageRegion<Input1ImageType>(input1, input1->GetLargestPossibleRegion(), bbInput1);    
163     typename BBType::Pointer bbInput2 = BBType::New();    
164     ComputeBBFromImageRegion<Input2ImageType>(input2, input2->GetLargestPossibleRegion(), bbInput2);
165     typename BBType::Pointer bbOutput = BBType::New();    
166     ComputeBBFromImageRegion<OutputImageType>(outputImage, outputImage->GetLargestPossibleRegion(), bbOutput);
167     
168     // DD(bbInput1);
169     // DD(bbInput2);
170     // DD(bbOutput);
171
172     typename BBType::Pointer bb = BBType::New();    
173     ComputeBBIntersection<Dim>(bb, bbInput1, bbInput2);
174     // DD(bb);
175     ComputeBBIntersection<Dim>(bb, bb, bbOutput);
176     // DD(bb);
177  
178     ComputeRegionFromBB<Input1ImageType>(input1, bb, input1Region);
179     ComputeRegionFromBB<Input2ImageType>(input2, bb, input2Region);
180     ComputeRegionFromBB<OutputImageType>(outputImage, bb, outputRegion);
181
182   }
183   //--------------------------------------------------------------------
184
185
186   //--------------------------------------------------------------------
187   template <class TInputImage1, class TInputImage2, class TOutputImage>
188   void 
189   BooleanOperatorLabelImageFilter<TInputImage1, TInputImage2, TOutputImage>::
190   GenerateInputRequestedRegion() {
191     // Call default
192     itk::InPlaceImageFilter<TInputImage1, TOutputImage>::GenerateInputRequestedRegion();
193     // Get input pointers and set requested region to common region
194     Input1ImagePointer input1 = dynamic_cast<TInputImage1*>(itk::ProcessObject::GetInput(0));
195     Input2ImagePointer input2 = dynamic_cast<TInputImage2*>(itk::ProcessObject::GetInput(1));
196     input1->SetRequestedRegion(input1Region);
197     input2->SetRequestedRegion(input2Region);  
198   }
199   //--------------------------------------------------------------------
200
201
202   //--------------------------------------------------------------------
203   template <class TInputImage1, class TInputImage2, class TOutputImage>
204   void 
205   BooleanOperatorLabelImageFilter<TInputImage1, TInputImage2, TOutputImage>::
206   GenerateData() {
207     // Get input pointers
208     Input1ImageConstPointer input1 = dynamic_cast<const TInputImage1*>(itk::ProcessObject::GetInput(0));
209     Input2ImageConstPointer input2 = dynamic_cast<const TInputImage2*>(itk::ProcessObject::GetInput(1));
210     
211     // Get output pointer
212     OutputImagePointer output = this->GetOutput(0);
213     
214     // Get Region iterators
215     // DD(input1Region);
216     // DD(input2Region);
217     // DD(outputRegion);
218     itk::ImageRegionConstIterator<Input1ImageType> it1(input1, input1Region);
219     itk::ImageRegionConstIterator<Input2ImageType> it2(input2, input2Region);
220     itk::ImageRegionIterator<OutputImageType>      ot (output, outputRegion);
221     it1.GoToBegin();
222     it2.GoToBegin();
223     ot.GoToBegin();
224
225     switch (m_OperationType) {
226     case AndNot: LoopAndNot(it1, it2, ot);  break;
227     case And: LoopAnd(it1, it2, ot);  break;
228     }
229   }
230   //--------------------------------------------------------------------
231   
232
233   //--------------------------------------------------------------------
234 #define LOOP_BEGIN(FUNCTION_NAME)                                       \
235   template <class TInputImage1, class TInputImage2, class TOutputImage> \
236   template <class Iter1, class Iter2>                                   \
237   void                                                                  \
238   BooleanOperatorLabelImageFilter<TInputImage1, TInputImage2, TOutputImage>:: \
239   FUNCTION_NAME(Iter1 it1, Iter1 it2, Iter2 ot) {                       \
240   while (!ot.IsAtEnd()) {
241   
242 #define LOOP_END ++it1; ++it2; ++ot; }}
243   //--------------------------------------------------------------------
244   
245
246   //--------------------------------------------------------------------
247   LOOP_BEGIN(LoopAndNot)
248   if ((it1.Get() != mBackgroundValue1) && (it2.Get() == mBackgroundValue2)) { ot.Set(mForegroundValue); }
249   else { ot.Set(mBackgroundValue); }
250   LOOP_END
251   //--------------------------------------------------------------------
252
253  
254   //--------------------------------------------------------------------
255   LOOP_BEGIN(LoopAnd)
256   if ((it1.Get() != mBackgroundValue1) && (it2.Get() != mBackgroundValue2)) { ot.Set(mForegroundValue); }
257   else { ot.Set(mBackgroundValue); }
258   LOOP_END
259   //--------------------------------------------------------------------
260
261  
262 }//end clitk
263  
264 #endif //#define CLITKBOOLEANOPERATORLABELIMAGEFILTER_TXX