1 /*=========================================================================
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.
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.
11 =========================================================================*/
13 #ifndef CLITKIMAGEARITHMGENERICFILTER_CXX
14 #define CLITKIMAGEARITHMGENERICFILTER_CXX
17 -------------------------------------------------------------------
18 * @file clitkImageArithmGenericFilter.cxx
19 * @author David Sarrut <David.Sarrut@creatis.insa-lyon.fr>
23 -------------------------------------------------------------------*/
25 #include "clitkImageArithmGenericFilter.h"
27 //--------------------------------------------------------------------
28 clitk::ImageArithmGenericFilter::ImageArithmGenericFilter()
29 :ImageToImageGenericFilter<Self>("ImageArithmGenericFilter"),mTypeOfOperation(0) {
30 InitializeImageType<2>();
31 InitializeImageType<3>();
32 InitializeImageType<4>();
33 mIsOperationUseASecondImage = false;
35 //--------------------------------------------------------------------
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, float);
43 /* ADD_IMAGE_TYPE(Dim, short);
44 ADD_IMAGE_TYPE(Dim, ushort;
45 ADD_IMAGE_TYPE(Dim, int);
46 ADD_IMAGE_TYPE(Dim, unsigned int);
47 ADD_IMAGE_TYPE(Dim, double);
50 //--------------------------------------------------------------------
53 //--------------------------------------------------------------------
54 template<class ImageType>
55 void clitk::ImageArithmGenericFilter::UpdateWithInputImageType() {
59 //DS TO BE CHANGED IN GetNumberOfInput() !!!!!!!!
61 if (mInputFilenames.size() == 0) {
62 std::cerr << "ERROR : please provide at least a input filename." << std::endl;
64 if (mInputFilenames.size() == 1) {
65 mIsOperationUseASecondImage = false;
67 if (mInputFilenames.size() == 2) {
68 mIsOperationUseASecondImage = true;
70 if (mInputFilenames.size() > 2) {
71 std::cerr << "ERROR : please provide only 1 or 2 input filenames." << std::endl;
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;
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);
87 outputImage = ComputeImage<ImageType>(input1);
91 this->SetNextOutput<ImageType>(outputImage);
93 //--------------------------------------------------------------------
95 //--------------------------------------------------------------------
96 template<class ImageType>
97 typename ImageType::Pointer
98 clitk::ImageArithmGenericFilter::ComputeImage(typename ImageType::Pointer inputImage) {
100 typedef typename ImageType::PixelType PixelType;
101 typedef itk::ImageRegionIterator<ImageType> IteratorType;
102 IteratorType it(inputImage, inputImage->GetLargestPossibleRegion());
105 switch (mTypeOfOperation) {
107 while (!it.IsAtEnd()) {
108 it.Set(PixelTypeDownCast<double, PixelType>((double)it.Get() + mScalar) );
113 while (!it.IsAtEnd()) {
114 it.Set(PixelTypeDownCast<double, PixelType>((double)it.Get() * mScalar) );
119 while (!it.IsAtEnd()) {
121 it.Set(PixelTypeDownCast<double, PixelType>(mScalar / (double)it.Get()));
122 else it.Set(mDefaultPixelValue);
127 while (!it.IsAtEnd()) {
128 if (it.Get() < mScalar) it.Set(PixelTypeDownCast<double, PixelType>(mScalar));
133 while (!it.IsAtEnd()) {
134 if (it.Get() > mScalar) it.Set(PixelTypeDownCast<double, PixelType>(mScalar));
138 case 5: // Absolute value
139 while (!it.IsAtEnd()) {
140 if (it.Get() <= 0) it.Set(PixelTypeDownCast<double, PixelType>(-it.Get()));
141 // <= zero to avoid warning for unsigned types
145 case 6: // Squared value
146 while (!it.IsAtEnd()) {
147 it.Set(PixelTypeDownCast<double, PixelType>((double)it.Get()*(double)it.Get()));
152 while (!it.IsAtEnd()) {
154 it.Set(PixelTypeDownCast<double, PixelType>(log((double)it.Get())));
155 else it.Set(mDefaultPixelValue);
160 while (!it.IsAtEnd()) {
161 it.Set(PixelTypeDownCast<double, PixelType>(exp((double)it.Get())));
166 while (!it.IsAtEnd()) {
168 it.Set(PixelTypeDownCast<double, PixelType>(sqrt((double)it.Get())));
170 if (it.Get() ==0) it.Set(0);
171 else it.Set(mDefaultPixelValue);
177 std::cerr << "ERROR : the operation number (" << mTypeOfOperation << ") is not known." << std::endl;
183 //--------------------------------------------------------------------
185 //--------------------------------------------------------------------
186 template<class ImageType1, class ImageType2>
187 typename ImageType1::Pointer
188 clitk::ImageArithmGenericFilter::ComputeImage(typename ImageType1::Pointer inputImage1,
189 typename ImageType2::Pointer inputImage2) {
191 typedef typename ImageType1::PixelType PixelType;
192 typedef itk::ImageRegionIterator<ImageType1> IteratorType;
193 IteratorType it1(inputImage1, inputImage1->GetLargestPossibleRegion());
196 typedef itk::ImageRegionConstIterator<ImageType2> ConstIteratorType;
197 ConstIteratorType it2(inputImage2, inputImage2->GetLargestPossibleRegion());
200 switch (mTypeOfOperation) {
202 while (!it1.IsAtEnd()) {
203 it1.Set(PixelTypeDownCast<double, PixelType>((double)it1.Get() + (double)it2.Get()) );
208 while (!it1.IsAtEnd()) {
209 it1.Set(PixelTypeDownCast<double, PixelType>((double)it1.Get() * (double)it2.Get()) );
214 while (!it1.IsAtEnd()) {
216 it1.Set(PixelTypeDownCast<double, PixelType>((double)it1.Get() / (double)it2.Get()));
217 else it1.Set(mDefaultPixelValue);
222 while (!it1.IsAtEnd()) {
223 if (it1.Get() < it2.Get()) it1.Set(PixelTypeDownCast<double, PixelType>(it2.Get()));
228 while (!it1.IsAtEnd()) {
229 if (it1.Get() > it2.Get()) it1.Set(PixelTypeDownCast<double, PixelType>(it2.Get()));
233 case 5: // Absolute difference
234 while (!it1.IsAtEnd()) {
235 it1.Set(PixelTypeDownCast<double, PixelType>(fabs(it2.Get()-it1.Get())));
239 case 6: // Squared differences
240 while (!it1.IsAtEnd()) {
241 it1.Set(PixelTypeDownCast<double, PixelType>(pow((double)it1.Get()-(double)it2.Get(),2)));
245 case 7: // Difference
246 while (!it1.IsAtEnd()) {
247 it1.Set(PixelTypeDownCast<double, PixelType>((double)it1.Get()-(double)it2.Get()));
251 case 8: // Relative Difference
252 while (!it1.IsAtEnd()) {
253 if (it1.Get() != 0) it1.Set(PixelTypeDownCast<double, PixelType>(((double)it1.Get()-(double)it2.Get()))/(double)it1.Get());
259 std::cerr << "ERROR : the operation number (" << mTypeOfOperation << ") is not known." << std::endl;
265 //--------------------------------------------------------------------
267 #endif //define CLITKIMAGEARITHMGENERICFILTER_CXX