]> Creatis software - clitk.git/blob - filters/clitkImageArithmGenericFilter.cxx
- new GF system
[clitk.git] / filters / clitkImageArithmGenericFilter.cxx
1 /*=========================================================================
2
3   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
4   l'Image). All rights reserved. See Doc/License.txt or
5   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
6                                                                                 
7      This software is distributed WITHOUT ANY WARRANTY; without even
8      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
9      PURPOSE.  See the above copyright notices for more information.
10                                                                              
11 =========================================================================*/
12
13 #ifndef CLITKIMAGEARITHMGENERICFILTER_CXX
14 #define CLITKIMAGEARITHMGENERICFILTER_CXX
15
16 /**
17  -------------------------------------------------------------------
18  * @file   clitkImageArithmGenericFilter.cxx
19  * @author David Sarrut <David.Sarrut@creatis.insa-lyon.fr>
20  * @date   23 Feb 2008
21
22  * @brief  
23  -------------------------------------------------------------------*/
24
25 #include "clitkImageArithmGenericFilter.h"
26
27 //--------------------------------------------------------------------
28 clitk::ImageArithmGenericFilter::ImageArithmGenericFilter()
29   :ImageToImageGenericFilter<Self>("ImageArithmGenericFilter"),mTypeOfOperation(0) {
30   InitializeImageType<2>();
31   InitializeImageType<3>();
32   InitializeImageType<4>();  
33   mIsOperationUseASecondImage = false;
34 }
35 //--------------------------------------------------------------------
36
37 //--------------------------------------------------------------------
38 template<unsigned int Dim>
39 void clitk::ImageArithmGenericFilter::InitializeImageType() {      
40   ADD_IMAGE_TYPE(Dim, char);
41   ADD_IMAGE_TYPE(Dim, short);
42   /*  ADD_IMAGE_TYPE(Dim, short);
43   ADD_IMAGE_TYPE(Dim, ushort;
44   ADD_IMAGE_TYPE(Dim, int);
45   ADD_IMAGE_TYPE(Dim, unsigned int);
46   ADD_IMAGE_TYPE(Dim, float);
47   ADD_IMAGE_TYPE(Dim, double);
48   */
49 }
50 //--------------------------------------------------------------------
51
52
53 //--------------------------------------------------------------------
54 template<class ImageType>
55 void clitk::ImageArithmGenericFilter::UpdateWithInputImageType() {
56
57   // Check Input
58
59   //DS TO BE CHANGED IN GetNumberOfInput() !!!!!!!!
60
61   if (mInputFilenames.size() == 0) {
62     std::cerr << "ERROR : please provide at least a input filename." << std::endl;
63   }
64   if (mInputFilenames.size() == 1) {
65     mIsOperationUseASecondImage = false;
66   }
67   if (mInputFilenames.size() == 2) {
68     mIsOperationUseASecondImage = true;
69   }
70   if (mInputFilenames.size() > 2) {
71     std::cerr << "ERROR : please provide only 1 or 2 input filenames." << std::endl;
72   }
73
74   // Read input1
75   //  typename ImageType::Pointer input1 = clitk::readImage<ImageType>(mInputFilenames[0], mIOVerbose);
76   typename ImageType::Pointer input1 = this->template GetInput<ImageType>(0);
77   typename ImageType::Pointer outputImage;  
78
79   // Read input2 (float is ok altough it could take too memory ...)
80   if (mIsOperationUseASecondImage) {
81     typedef itk::Image<float,ImageType::ImageDimension> ImageType2;
82     //    typename ImageType2::Pointer input2 = clitk::readImage<ImageType2>(mInputFilenames[1], mIOVerbose);
83     typename ImageType2::Pointer input2 = this->template GetInput<ImageType2>(1);
84     outputImage = ComputeImage<ImageType, ImageType2>(input1, input2);
85   }
86   else {
87     outputImage = ComputeImage<ImageType>(input1);
88   }
89
90   // Write results
91   this->SetNextOutput<ImageType>(outputImage);
92   //clitk::writeImage<ImageType>(outputImage, mOutputFilename, mIOVerbose);
93 }
94 //--------------------------------------------------------------------
95
96 //--------------------------------------------------------------------
97 template<class ImageType>
98 typename ImageType::Pointer 
99 clitk::ImageArithmGenericFilter::ComputeImage(typename ImageType::Pointer inputImage) {
100
101   typedef typename ImageType::PixelType PixelType;
102   typedef itk::ImageRegionIterator<ImageType> IteratorType;
103   IteratorType it(inputImage, inputImage->GetLargestPossibleRegion());
104   it.GoToBegin();
105   
106   switch (mTypeOfOperation) {
107   case 0: // Addition
108     while (!it.IsAtEnd()) {
109       it.Set(PixelTypeDownCast<double, PixelType>((double)it.Get() + mScalar) ); 
110       ++it;
111     }
112     break;
113   case 1: // Multiply
114     while (!it.IsAtEnd()) {
115       it.Set(PixelTypeDownCast<double, PixelType>((double)it.Get() * mScalar) ); 
116       ++it;
117     }
118     break;
119   case 2: // Inverse
120     while (!it.IsAtEnd()) {
121       if (it.Get() != 0)
122         it.Set(PixelTypeDownCast<double, PixelType>(mScalar / (double)it.Get())); 
123       else it.Set(mDefaultPixelValue);
124       ++it;
125     }
126     break;
127   case 3: // Max 
128     while (!it.IsAtEnd()) {
129       if (it.Get() < mScalar) it.Set(PixelTypeDownCast<double, PixelType>(mScalar)); 
130       ++it;
131     }
132     break;
133   case 4: // Min
134     while (!it.IsAtEnd()) {
135       if (it.Get() > mScalar) it.Set(PixelTypeDownCast<double, PixelType>(mScalar)); 
136       ++it;
137     }
138     break;
139   case 5: // Absolute value 
140     while (!it.IsAtEnd()) {
141       if (it.Get() <= 0) it.Set(PixelTypeDownCast<double, PixelType>(-it.Get())); 
142       // <= zero to avoid warning for unsigned types
143       ++it;
144     }
145     break;
146   case 6: // Squared value
147     while (!it.IsAtEnd()) {
148       it.Set(PixelTypeDownCast<double, PixelType>((double)it.Get()*(double)it.Get())); 
149       ++it;
150     }
151     break;
152   case 7: // Log
153     while (!it.IsAtEnd()) {
154       if (it.Get() > 0) 
155         it.Set(PixelTypeDownCast<double, PixelType>(log((double)it.Get()))); 
156       else it.Set(mDefaultPixelValue);
157       ++it;
158     }
159     break;
160   case 8: // exp
161     while (!it.IsAtEnd()) {
162       it.Set(PixelTypeDownCast<double, PixelType>(exp((double)it.Get()))); 
163       ++it;
164     }
165     break;
166   case 9: // sqrt
167     while (!it.IsAtEnd()) {
168       if (it.Get() > 0) 
169         it.Set(PixelTypeDownCast<double, PixelType>(sqrt((double)it.Get()))); 
170       else {
171         if (it.Get() ==0) it.Set(0);
172         else it.Set(mDefaultPixelValue);
173       }
174       ++it;
175     }
176     break;
177   default: // error ?
178     std::cerr << "ERROR : the operation number (" << mTypeOfOperation << ") is not known." << std::endl;
179     exit(-1);
180   }
181
182   return inputImage;
183 }
184 //--------------------------------------------------------------------
185
186 //--------------------------------------------------------------------
187 template<class ImageType1, class ImageType2>
188 typename ImageType1::Pointer
189 clitk::ImageArithmGenericFilter::ComputeImage(typename ImageType1::Pointer inputImage1, 
190                                        typename ImageType2::Pointer inputImage2) {
191
192   typedef typename ImageType1::PixelType PixelType;
193   typedef itk::ImageRegionIterator<ImageType1> IteratorType;
194   IteratorType it1(inputImage1, inputImage1->GetLargestPossibleRegion());
195   it1.GoToBegin();
196   
197   typedef itk::ImageRegionConstIterator<ImageType2> ConstIteratorType;
198   ConstIteratorType it2(inputImage2, inputImage2->GetLargestPossibleRegion());
199   it2.GoToBegin();
200   
201   switch (mTypeOfOperation) {
202   case 0: // Addition
203     while (!it1.IsAtEnd()) {
204       it1.Set(PixelTypeDownCast<double, PixelType>((double)it1.Get() + (double)it2.Get()) ); 
205       ++it1; ++it2;
206     }
207     break;
208   case 1: // Multiply
209     while (!it1.IsAtEnd()) {
210       it1.Set(PixelTypeDownCast<double, PixelType>((double)it1.Get() * (double)it2.Get()) ); 
211       ++it1; ++it2;
212     }
213     break;
214   case 2: // Divide
215     while (!it1.IsAtEnd()) {
216       if (it1.Get() != 0)
217         it1.Set(PixelTypeDownCast<double, PixelType>((double)it1.Get() / (double)it2.Get())); 
218       else it1.Set(mDefaultPixelValue);
219       ++it1; ++it2;
220     }
221     break;
222   case 3: // Max 
223     while (!it1.IsAtEnd()) {
224       if (it1.Get() < it2.Get()) it1.Set(PixelTypeDownCast<double, PixelType>(it2.Get())); 
225       ++it1; ++it2;
226     }
227     break;
228   case 4: // Min
229     while (!it1.IsAtEnd()) {
230       if (it1.Get() > it2.Get()) it1.Set(PixelTypeDownCast<double, PixelType>(it2.Get())); 
231       ++it1; ++it2;
232     }
233     break;
234   case 5: // Absolute difference
235     while (!it1.IsAtEnd()) {
236       it1.Set(PixelTypeDownCast<double, PixelType>(fabs(it2.Get()-it1.Get()))); 
237       ++it1; ++it2;
238     }
239     break;
240   case 6: // Squared differences
241     while (!it1.IsAtEnd()) {
242       it1.Set(PixelTypeDownCast<double, PixelType>(pow((double)it1.Get()-(double)it2.Get(),2))); 
243       ++it1; ++it2;
244     }
245     break;
246   case 7: // Difference
247     while (!it1.IsAtEnd()) {
248       it1.Set(PixelTypeDownCast<double, PixelType>((double)it1.Get()-(double)it2.Get())); 
249       ++it1; ++it2;
250     }
251     break;
252   case 8: // Relative Difference
253     while (!it1.IsAtEnd()) {
254       if (it1.Get() != 0) it1.Set(PixelTypeDownCast<double, PixelType>(((double)it1.Get()-(double)it2.Get()))/(double)it1.Get()); 
255       else it1.Set(0.0);
256       ++it1; ++it2;
257     }
258     break;
259   default: // error ?
260     std::cerr << "ERROR : the operation number (" << mTypeOfOperation << ") is not known." << std::endl;
261     exit(-1);
262   }
263
264   return inputImage1;
265 }
266 //--------------------------------------------------------------------
267
268 #endif //define CLITKIMAGEARITHMGENERICFILTER_CXX