itkTestMainExtended.h

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Adapted from itkTestMain.h available in ITK: www.itk.org
00004 
00005   Portion of this code are covered under the ITK Copyright
00006   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
00007 
00008   Portions of this code are covered under the VTK copyright.
00009   See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.
00010 
00011      This software is distributed WITHOUT ANY WARRANTY; without even 
00012      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00013      PURPOSE.  See the above copyright notices for more information.
00014 
00015 =========================================================================*/
00016 #ifndef __itkTestMainDTI_h
00017 #define __itkTestMainDTI_h
00018 
00019 // This file is used to create TestDriver executables
00020 // These executables are able to register a function pointer to a string name
00021 // in a lookup table.   By including this file, it creates a main function
00022 // that calls RegisterTests() then looks up the function pointer for the test
00023 // specified on the command line.
00024 #include "itkWin32Header.h"
00025 #include <map>
00026 #include <string>
00027 #include <iostream>
00028 #include <fstream>
00029 #include "itkNumericTraits.h"
00030 #include "itkMultiThreader.h"
00031 #include "itkImage.h"
00032 #include "itkImageFileReader.h"
00033 #include "itkImageFileWriter.h"
00034 #include "itkImageRegionConstIterator.h"
00035 #include "itkSubtractImageFilter.h"
00036 #include "itkRescaleIntensityImageFilter.h"
00037 #include "itkExtractImageFilter.h"
00038 #include "itkDifferenceImageFilter.h"
00039 #include "itkDifferenceDiffusionTensor3DImageFilter.h"
00040 #include "itkDiffusionTensor3D.h"
00041 #include "itkImageRegion.h"
00042 #include "itksys/SystemTools.hxx"
00043 #include <itkTensorFractionalAnisotropyImageFilter.h>
00044 
00045 #define ITK_TEST_DIMENSION_MAX 6
00046 
00047 typedef int (*MainFuncPointer)(int , char* [] );
00048 std::map<std::string, MainFuncPointer> StringToTestFunctionMap;
00049 
00050 #define REGISTER_TEST(test) \
00051 extern int test(int, char* [] ); \
00052 StringToTestFunctionMap[#test] = test
00053 
00054 int RegressionTestImage (const char *testImageFilename, 
00055                          const char *baselineImageFilename, 
00056                          int reportErrors,
00057                          double intensityTolerance = 2.0,
00058                          unsigned int numberOfPixelsTolerance = 0,
00059                          unsigned int radiusTolerance = 0);
00060 
00061 std::map<std::string,int> RegressionTestBaselines (char *);
00062 
00063 void RegisterTests();
00064 void PrintAvailableTests()
00065 {
00066   std::cout << "Available tests:\n";
00067   std::map<std::string, MainFuncPointer>::iterator j = StringToTestFunctionMap.begin();
00068   int i = 0;
00069   while(j != StringToTestFunctionMap.end())
00070     {
00071     std::cout << i << ". " << j->first << "\n";
00072     ++i;
00073     ++j;
00074     }
00075 }
00076 
00077 int main(int ac, char* av[] )
00078 {
00079   double intensityTolerance  = 2.0;
00080   unsigned int numberOfPixelsTolerance = 0;
00081   unsigned int radiusTolerance = 0;
00082 
00083   typedef std::pair< char *, char *> ComparePairType;
00084   std::vector< ComparePairType > compareList;
00085 
00086   RegisterTests();
00087   std::string testToRun;
00088   if(ac < 2)
00089     {
00090     PrintAvailableTests();
00091     std::cout << "To run a test, enter the test number: ";
00092     int testNum = 0;
00093     std::cin >> testNum;
00094     std::map<std::string, MainFuncPointer>::iterator j = StringToTestFunctionMap.begin();
00095     int i = 0;
00096     while(j != StringToTestFunctionMap.end() && i < testNum)
00097       {
00098       ++i;
00099       ++j;
00100       }
00101     if(j == StringToTestFunctionMap.end())
00102       {
00103       std::cerr << testNum << " is an invalid test number\n";
00104       return -1;
00105       }
00106     testToRun = j->first;
00107     }
00108   else
00109     {
00110     while( ac > 0 && testToRun.empty() )
00111       {
00112       if (strcmp(av[1], "--with-threads") == 0)
00113         {
00114         int numThreads = atoi(av[2]);
00115         itk::MultiThreader::SetGlobalDefaultNumberOfThreads(numThreads);
00116         av += 2;
00117         ac -= 2;
00118         }
00119       else if (strcmp(av[1], "--without-threads") == 0)
00120         {
00121         itk::MultiThreader::SetGlobalDefaultNumberOfThreads(1);
00122         av += 1;
00123         ac -= 1;
00124         }
00125       else if (ac > 3 && strcmp(av[1], "--compare") == 0)
00126         {
00127         compareList.push_back( ComparePairType( av[2], av[3] ) );
00128         av += 3;
00129         ac -= 3;
00130         }
00131       else if (ac > 2 && strcmp(av[1], "--compareNumberOfPixelsTolerance") == 0)
00132         {
00133         numberOfPixelsTolerance = atoi( av[2] );
00134         av += 2;
00135         ac -= 2;
00136         }
00137       else if (ac > 2 && strcmp(av[1], "--compareRadiusTolerance") == 0)
00138         {
00139         radiusTolerance = atoi( av[2] );
00140         av += 2;
00141         ac -= 2;
00142         }
00143       else if (ac > 2 && strcmp(av[1], "--compareIntensityTolerance") == 0)
00144         {
00145         intensityTolerance = atof( av[2] );
00146         av += 2;
00147         ac -= 2;
00148         }
00149       else
00150         {
00151         testToRun = av[1];
00152         }
00153       }
00154     }
00155   std::map<std::string, MainFuncPointer>::iterator j = StringToTestFunctionMap.find(testToRun);
00156   if(j != StringToTestFunctionMap.end())
00157     {
00158     MainFuncPointer f = j->second;
00159     int result;
00160     try
00161       {
00162       // Invoke the test's "main" function.
00163       result = (*f)(ac-1, av+1);
00164       // Make a list of possible baselines
00165       for( int i=0; i<static_cast<int>(compareList.size()); i++)
00166         {
00167         char * baselineFilename = compareList[i].first;
00168         char * testFilename = compareList[i].second;
00169         std::map<std::string,int> baselines = RegressionTestBaselines(baselineFilename);
00170         std::map<std::string,int>::iterator baseline = baselines.begin();
00171         std::string bestBaseline;
00172         int bestBaselineStatus = itk::NumericTraits<int>::max();
00173         while (baseline != baselines.end())
00174           {
00175           baseline->second = RegressionTestImage(testFilename,
00176                                                  (baseline->first).c_str(),
00177                                                  0, 
00178                                                  intensityTolerance, 
00179                                                  numberOfPixelsTolerance, 
00180                                                  radiusTolerance );
00181           if (baseline->second < bestBaselineStatus)
00182             {
00183             bestBaseline = baseline->first;
00184             bestBaselineStatus = baseline->second;
00185             }
00186           if (baseline->second == 0)
00187             {
00188             break;
00189             }
00190           ++baseline;
00191           }
00192         // if the best we can do still has errors, generate the error images
00193          if (bestBaselineStatus)
00194           {
00195           RegressionTestImage(testFilename,
00196                               bestBaseline.c_str(),
00197                               1, 
00198                               intensityTolerance,
00199                               numberOfPixelsTolerance, 
00200                               radiusTolerance );
00201           }
00202 
00203         // output the matching baseline
00204         std::cout << "<DartMeasurement name=\"BaselineImageName\" type=\"text/string\">";
00205         std::cout << itksys::SystemTools::GetFilenameName(bestBaseline);
00206         std::cout << "</DartMeasurement>" << std::endl;
00207         
00208         result += bestBaselineStatus;
00209         }
00210       }
00211     catch(const itk::ExceptionObject& e)
00212       {
00213       std::cerr << "ITK test driver caught an ITK exception:\n";
00214       e.Print(std::cerr);
00215       result = -1;
00216       }
00217     catch(const std::exception& e)
00218       {
00219       std::cerr << "ITK test driver caught an exception:\n";
00220       std::cerr << e.what() << "\n";
00221       result = -1;
00222       }
00223     catch(...)
00224       {
00225       std::cerr << "ITK test driver caught an unknown exception!!!\n";
00226       result = -1;
00227       }
00228     return result;
00229     }
00230   PrintAvailableTests();
00231   std::cerr << "Failed: " << testToRun << ": No test registered with name " << testToRun << "\n";
00232   return -1;
00233 }
00234 
00235 
00236 
00237 
00238 // Regression Testing Code
00239 
00240 //What pixeltype is the image 
00241 void GetImageType( const char* fileName ,
00242                    itk::ImageIOBase::IOPixelType &pixelType ,
00243                    itk::ImageIOBase::IOComponentType &componentType )
00244 {
00245    typedef itk::Image< unsigned char , 3 > ImageType ;
00246    itk::ImageFileReader< ImageType >::Pointer imageReader =
00247          itk::ImageFileReader< ImageType >::New();
00248    imageReader->SetFileName( fileName ) ;
00249    imageReader->UpdateOutputInformation() ;
00250    pixelType = imageReader->GetImageIO()->GetPixelType() ;
00251    componentType = imageReader->GetImageIO()->GetComponentType() ;
00252 }
00253 
00254 template< class ImageType >
00255 int ReadImages(  const char* baselineImageFilename ,
00256                  const char* testImageFilename ,
00257                  typename ImageType::Pointer &baselineImage ,
00258                  typename ImageType::Pointer &testImage
00259               )
00260 {
00261    typedef itk::ImageFileReader< ImageType > ReaderType ;
00262    // Read the baseline file
00263    typename ReaderType::Pointer baselineReader = ReaderType::New() ;
00264    baselineReader->SetFileName( baselineImageFilename ) ;
00265    try
00266 {
00267    baselineReader->UpdateLargestPossibleRegion() ;
00268 }
00269       catch (itk::ExceptionObject& e)
00270 {
00271    std::cerr << "Exception detected while reading " << baselineImageFilename << " : "  << e.GetDescription();
00272    return 1000;
00273 }
00274 
00275       // Read the file generated by the test
00276    typename ReaderType::Pointer testReader = ReaderType::New() ;
00277    testReader->SetFileName( testImageFilename ) ;
00278    try
00279    {
00280       testReader->UpdateLargestPossibleRegion() ;
00281    }
00282    catch (itk::ExceptionObject& e)
00283    {
00284       std::cerr << "Exception detected while reading " << testImageFilename << " : "  << e.GetDescription() << std::endl;
00285       return 1000;
00286    }
00287         // The sizes of the baseline and test image must match
00288       typename ImageType::SizeType baselineSize;
00289       baselineSize = baselineReader->GetOutput()->GetLargestPossibleRegion().GetSize();
00290       typename ImageType::SizeType testSize;
00291       testSize = testReader->GetOutput()->GetLargestPossibleRegion().GetSize();
00292   
00293       if (baselineSize != testSize)
00294 {
00295    std::cerr << "The size of the Baseline image and Test image do not match!" << std::endl;
00296    std::cerr << "Baseline image: " << baselineImageFilename
00297          << " has size " << baselineSize << std::endl;
00298    std::cerr << "Test image:     " << testImageFilename
00299          << " has size " << testSize << std::endl;
00300    return 1;
00301 }
00302 baselineImage = baselineReader->GetOutput() ;
00303 testImage = testReader->GetOutput() ;
00304 return 0 ;
00305 }
00306 
00307 int RegressionTestImage (const char *testImageFilename, 
00308                          const char *baselineImageFilename, 
00309                          int reportErrors,
00310                          double intensityTolerance,
00311                          unsigned int numberOfPixelsTolerance, 
00312                          unsigned int radiusTolerance )
00313 {
00314   // Use the factory mechanism to read the test and baseline files and convert them to double
00315   typedef itk::Image<double,ITK_TEST_DIMENSION_MAX>        ImageType;
00316   typedef itk::Image<itk::DiffusionTensor3D<double>,ITK_TEST_DIMENSION_MAX>        DiffusionImageType;
00317   typedef itk::Image<unsigned char,ITK_TEST_DIMENSION_MAX> OutputType;
00318   typedef itk::Image<unsigned char,2>                      DiffOutputType;
00319 
00320 
00321   
00322   itk::ImageIOBase::IOPixelType pixelTypeBaseline ;
00323   itk::ImageIOBase::IOComponentType componentTypeBaseline ;
00324   GetImageType( baselineImageFilename , pixelTypeBaseline , componentTypeBaseline ) ;
00325   itk::ImageIOBase::IOPixelType pixelTypeTestImage ;
00326   itk::ImageIOBase::IOComponentType componentTypeTestImage ;
00327   GetImageType( testImageFilename , pixelTypeTestImage , componentTypeTestImage ) ;
00328   bool diffusion = false ;
00329   //check if the voxels of the image are diffusion tensors
00330   if( ( pixelTypeBaseline == itk::ImageIOBase::SYMMETRICSECONDRANKTENSOR
00331         || pixelTypeBaseline == itk::ImageIOBase::DIFFUSIONTENSOR3D
00332       )
00333         && ( pixelTypeTestImage == itk::ImageIOBase::SYMMETRICSECONDRANKTENSOR
00334         || pixelTypeTestImage == itk::ImageIOBase::DIFFUSIONTENSOR3D
00335            )
00336     )
00337   {
00338      diffusion = true ;
00339   }
00340   ImageType::Pointer baselineImage ;
00341   ImageType::Pointer testImage ;
00342   DiffusionImageType::Pointer diffusionBaselineImage ;
00343   DiffusionImageType::Pointer diffusionTestImage ;
00344   unsigned long status = 0;
00345   typedef itk::DifferenceImageFilter<ImageType,ImageType> DiffType;
00346   DiffType::Pointer diff ;
00347   typedef itk::DifferenceDiffusionTensor3DImageFilter<DiffusionImageType,ImageType> DiffusionDiffType;
00348   DiffusionDiffType::Pointer diffusiondiff ;
00349   int returnValue ;
00350   //If it is not a DTI, we load the image as a scalar image
00351   if( !diffusion )
00352   {
00353      returnValue = ReadImages< ImageType >( baselineImageFilename ,
00354                                             testImageFilename ,
00355                                             baselineImage ,
00356                                             testImage
00357                                           ) ;
00358      if( returnValue )
00359      {
00360         return returnValue ;
00361      }
00362   // Now compare the two images
00363       diff = DiffType::New();
00364       diff->SetValidInput( baselineImage ) ;
00365       diff->SetTestInput( testImage ) ;
00366       diff->SetDifferenceThreshold( intensityTolerance );
00367       diff->SetToleranceRadius( radiusTolerance );
00368       diff->UpdateLargestPossibleRegion();
00369       status = diff->GetNumberOfPixelsWithDifferences();
00370 
00371   }
00372   else
00373   {//otherwise we load the image as a DTI
00374      returnValue = ReadImages< DiffusionImageType >( baselineImageFilename ,
00375                                                      testImageFilename ,
00376                                                      diffusionBaselineImage ,
00377                                                      diffusionTestImage
00378                                                    ) ;
00379      if( returnValue )
00380      {
00381         return returnValue ;
00382      }
00383      // Now compare the two images
00384      diffusiondiff = DiffusionDiffType::New();
00385      diffusiondiff->SetValidInput( diffusionBaselineImage ) ;
00386      diffusiondiff->SetTestInput(diffusionTestImage ) ;
00387      diffusiondiff->SetDifferenceThreshold( intensityTolerance );
00388      diffusiondiff->SetToleranceRadius( radiusTolerance );
00389      diffusiondiff->UpdateLargestPossibleRegion();
00390      status = diffusiondiff->GetNumberOfPixelsWithDifferences();
00391   }
00392 
00393   // if there are discrepencies, create an diff image
00394   if ( (status > numberOfPixelsTolerance) && reportErrors )
00395     {
00396     typedef itk::RescaleIntensityImageFilter<ImageType,OutputType> RescaleType;
00397     typedef itk::ExtractImageFilter<OutputType,DiffOutputType>     ExtractType;
00398     typedef itk::ImageFileWriter<DiffOutputType>                   WriterType;
00399     typedef itk::ImageRegion<ITK_TEST_DIMENSION_MAX>               RegionType;
00400     OutputType::SizeType size; size.Fill(0);
00401 
00402     RescaleType::Pointer rescale = RescaleType::New();
00403       rescale->SetOutputMinimum(itk::NumericTraits<unsigned char>::NonpositiveMin());
00404       rescale->SetOutputMaximum(itk::NumericTraits<unsigned char>::max());
00405       if( !diffusion )
00406       {
00407          rescale->SetInput(diff->GetOutput());
00408       }
00409       else
00410       {
00411          rescale->SetInput(diffusiondiff->GetOutput());
00412       }
00413       rescale->UpdateLargestPossibleRegion();
00414     size = rescale->GetOutput()->GetLargestPossibleRegion().GetSize();
00415 
00416     //Get the center slice of the image,  In 3D, the first slice
00417     //is often a black slice with little debugging information.
00418     OutputType::IndexType index; index.Fill(0);
00419     for (unsigned int i = 2; i < ITK_TEST_DIMENSION_MAX; i++)
00420       {
00421       index[i]=size[i]/2;//NOTE: Integer Divide used to get approximately the center slice
00422       size[i] = 0;
00423       }
00424 
00425     RegionType region;
00426     region.SetIndex(index);
00427 
00428     region.SetSize(size);
00429 
00430     ExtractType::Pointer extract = ExtractType::New();
00431       extract->SetInput(rescale->GetOutput());
00432       extract->SetExtractionRegion(region);
00433 
00434     WriterType::Pointer writer = WriterType::New();
00435       writer->SetInput(extract->GetOutput());
00436 
00437     std::cout << "<DartMeasurement name=\"ImageError\" type=\"numeric/double\">";
00438     std::cout << status;
00439     std::cout <<  "</DartMeasurement>" << std::endl;
00440 
00441     ::itk::OStringStream diffName;
00442       diffName << testImageFilename << ".diff.png";
00443     try
00444       {
00445          if( !diffusion )
00446          {
00447             rescale->SetInput(diff->GetOutput());
00448          }
00449          else
00450          {
00451             rescale->SetInput(diffusiondiff->GetOutput());
00452          }
00453       rescale->Update();
00454       }
00455     catch(const std::exception& e)
00456       {
00457       std::cerr << "Error during rescale of " << diffName.str() << std::endl;
00458       std::cerr << e.what() << "\n";
00459       }
00460     catch (...)
00461       {
00462       std::cerr << "Error during rescale of " << diffName.str() << std::endl;
00463       }
00464     writer->SetFileName(diffName.str().c_str());
00465     try
00466       {
00467       writer->Update();
00468       }
00469     catch(const std::exception& e)
00470       {
00471       std::cerr << "Error during write of " << diffName.str() << std::endl;
00472       std::cerr << e.what() << "\n";
00473       }
00474     catch (...)
00475       {
00476       std::cerr << "Error during write of " << diffName.str() << std::endl;
00477       }
00478 
00479     std::cout << "<DartMeasurementFile name=\"DifferenceImage\" type=\"image/png\">";
00480     std::cout << diffName.str();
00481     std::cout << "</DartMeasurementFile>" << std::endl;
00482     
00483     ImageType::Pointer testFA ;
00484     ImageType::Pointer baselineFA ;
00485     //We need a scalar image to show the differences between the baseline image and the test image.
00486     //We compute the FA of both diffusion tensor images
00487     if( diffusion )
00488     {
00489        typedef itk::TensorFractionalAnisotropyImageFilter< DiffusionImageType , ImageType > FAFilterType ;
00490        FAFilterType::Pointer testFAfilter = FAFilterType::New() ;
00491        diffusionTestImage->SetRequestedRegion( region ) ;
00492        testFAfilter->SetInput( diffusionTestImage ) ;
00493        testFAfilter->Update() ;
00494        testFA = testFAfilter->GetOutput() ;
00495        
00496        FAFilterType::Pointer baselineFAfilter = FAFilterType::New() ;
00497        diffusionBaselineImage->SetRequestedRegion( region ) ;
00498        baselineFAfilter->SetInput( diffusionBaselineImage ) ;
00499        baselineFAfilter->Update() ;
00500        baselineFA = baselineFAfilter->GetOutput() ;
00501     }
00502     
00503     ::itk::OStringStream baseName;
00504     if( !diffusion )
00505     {
00506       baseName << testImageFilename << ".base.png";
00507     }
00508     else
00509     {
00510        baseName << testImageFilename << ".FA.base.png";
00511     }
00512     try
00513       {
00514          if( !diffusion )
00515          {
00516             rescale->SetInput( baselineImage ) ;
00517          }
00518          else
00519          {
00520             rescale->SetInput( baselineFA ) ;
00521          }
00522       rescale->Update();
00523       }
00524     catch(const std::exception& e)
00525       {
00526       std::cerr << "Error during rescale of " << baseName.str() << std::endl;
00527       std::cerr << e.what() << "\n";
00528       }
00529     catch (...)
00530       {
00531       std::cerr << "Error during rescale of " << baseName.str() << std::endl;
00532       }
00533     try
00534       {
00535       writer->SetFileName(baseName.str().c_str());
00536       writer->Update();
00537       }
00538     catch(const std::exception& e)
00539       {
00540       std::cerr << "Error during write of " << baseName.str() << std::endl;
00541       std::cerr << e.what() << "\n";
00542       }
00543     catch (...)
00544       {
00545       std::cerr << "Error during write of " << baseName.str() << std::endl;
00546       }
00547 
00548     std::cout << "<DartMeasurementFile name=\"BaselineImage\" type=\"image/png\">";
00549     std::cout << baseName.str();
00550     std::cout << "</DartMeasurementFile>" << std::endl;
00551 
00552     ::itk::OStringStream testName;
00553     if( !diffusion )
00554     {
00555       testName << testImageFilename << ".test.png";
00556     }
00557     else
00558     {
00559        testName << testImageFilename << ".FA.test.png";
00560     }
00561     try
00562       {
00563          if( !diffusion )
00564          {
00565          rescale->SetInput( testImage ) ;
00566          }
00567          else
00568          {
00569             rescale->SetInput(testFA);
00570          }
00571       rescale->Update();
00572       }
00573     catch(const std::exception& e)
00574       {
00575       std::cerr << "Error during rescale of " << testName.str() << std::endl;
00576       std::cerr << e.what() << "\n";
00577       }
00578     catch (...)
00579       {
00580       std::cerr << "Error during rescale of " << testName.str() << std::endl;
00581       }
00582     try
00583       {
00584       writer->SetFileName(testName.str().c_str());
00585       writer->Update();
00586       }
00587     catch(const std::exception& e)
00588       {
00589       std::cerr << "Error during write of " << testName.str() << std::endl;
00590       std::cerr << e.what() << "\n";
00591       }
00592     catch (...)
00593       {
00594       std::cerr << "Error during write of " << testName.str() << std::endl;
00595       }
00596 
00597     std::cout << "<DartMeasurementFile name=\"TestImage\" type=\"image/png\">";
00598     std::cout << testName.str();
00599     std::cout << "</DartMeasurementFile>" << std::endl;
00600     }
00601 
00602   return (status > numberOfPixelsTolerance) ? 1 : 0;
00603 }
00604 
00605 //
00606 // Generate all of the possible baselines
00607 // The possible baselines are generated fromn the baselineFilename using the following algorithm:
00608 // 1) strip the suffix
00609 // 2) append a digit .x
00610 // 3) append the original suffix.
00611 // It the file exists, increment x and continue
00612 //
00613 std::map<std::string,int> RegressionTestBaselines (char *baselineFilename)
00614 {
00615   std::map<std::string,int> baselines;
00616   baselines[std::string(baselineFilename)] = 0;
00617 
00618   std::string originalBaseline(baselineFilename);
00619 
00620   int x = 0;
00621   std::string::size_type suffixPos = originalBaseline.rfind(".");
00622   std::string suffix;
00623   if (suffixPos != std::string::npos)
00624     {
00625     suffix = originalBaseline.substr(suffixPos,originalBaseline.length());
00626     originalBaseline.erase(suffixPos,originalBaseline.length());
00627     }
00628   while (++x)
00629     {
00630     ::itk::OStringStream filename;
00631     filename << originalBaseline << "." << x << suffix;
00632     std::ifstream filestream(filename.str().c_str());
00633     if (!filestream)
00634       {
00635       break;
00636       }
00637     baselines[filename.str()] = 0;
00638     filestream.close();
00639     }
00640   return baselines;
00641 }
00642 
00643 // Needed for explicit instantiation
00644 #include "itkDifferenceImageFilter.txx"
00645 #include "itkDifferenceDiffusionTensor3DImageFilter.txx"
00646 
00647 #endif

Generated on 6 Apr 2011 for Slicer3 by  doxygen 1.6.1