20 #ifndef __itkTestMain_h
21 #define __itkTestMain_h
33 #include "itkNumericTraits.h"
44 #include "itksys/SystemTools.hxx"
46 #define ITK_TEST_DIMENSION_MAX 6
51 #define REGISTER_TEST(test) \
52 extern int test(int, char* [] ); \
53 StringToTestFunctionMap[#test] = test
56 const char *baselineImageFilename,
58 double intensityTolerance = 2.0,
59 unsigned int numberOfPixelsTolerance = 0,
60 unsigned int radiusTolerance = 0);
67 std::cout <<
"Available tests:\n";
68 std::map<std::string, MainFuncPointer>::iterator j = StringToTestFunctionMap.begin();
70 while(j != StringToTestFunctionMap.end())
72 std::cout << i <<
". " << j->first <<
"\n";
78 int main(
int ac,
char* av[] )
80 double intensityTolerance = 2.0;
81 unsigned int numberOfPixelsTolerance = 0;
82 unsigned int radiusTolerance = 0;
84 typedef std::pair< char *, char *> ComparePairType;
85 std::vector< ComparePairType > compareList;
88 std::string testToRun;
92 std::cout <<
"To run a test, enter the test number: ";
95 std::map<std::string, MainFuncPointer>::iterator j = StringToTestFunctionMap.begin();
97 while(j != StringToTestFunctionMap.end() && i < testNum)
102 if(j == StringToTestFunctionMap.end())
104 std::cerr << testNum <<
" is an invalid test number\n";
107 testToRun = j->first;
111 while( ac > 0 && testToRun.empty() )
113 if (strcmp(av[1],
"--with-threads") == 0)
115 int numThreads = atoi(av[2]);
120 else if (strcmp(av[1],
"--without-threads") == 0)
126 else if (ac > 3 && strcmp(av[1],
"--compare") == 0)
128 compareList.push_back( ComparePairType( av[2], av[3] ) );
132 else if (ac > 2 && strcmp(av[1],
"--compareNumberOfPixelsTolerance") == 0)
134 numberOfPixelsTolerance = atoi( av[2] );
138 else if (ac > 2 && strcmp(av[1],
"--compareRadiusTolerance") == 0)
140 radiusTolerance = atoi( av[2] );
144 else if (ac > 2 && strcmp(av[1],
"--compareIntensityTolerance") == 0)
146 intensityTolerance = atof( av[2] );
156 std::map<std::string, MainFuncPointer>::iterator j = StringToTestFunctionMap.find(testToRun);
157 if(j != StringToTestFunctionMap.end())
164 result = (*f)(ac-1, av+1);
167 for(
int i=0; i<static_cast<int>(compareList.size()); i++)
169 char * baselineFilename = compareList[i].first;
170 char * testFilename = compareList[i].second;
172 std::map<std::string,int>::iterator baseline = baselines.begin();
173 std::string bestBaseline;
174 int bestBaselineStatus = itk::NumericTraits<int>::max();
175 while (baseline != baselines.end())
178 (baseline->first).c_str(),
181 numberOfPixelsTolerance,
183 if (baseline->second < bestBaselineStatus)
185 bestBaseline = baseline->first;
186 bestBaselineStatus = baseline->second;
188 if (baseline->second == 0)
195 if (bestBaselineStatus)
198 bestBaseline.c_str(),
201 numberOfPixelsTolerance,
206 std::cout <<
"<DartMeasurement name=\"BaselineImageName\" type=\"text/string\">";
207 std::cout << itksys::SystemTools::GetFilenameName(bestBaseline);
208 std::cout <<
"</DartMeasurement>" << std::endl;
210 result += bestBaselineStatus;
215 std::cerr <<
"ITK test driver caught an ITK exception:\n";
219 catch(
const std::exception& e)
221 std::cerr <<
"ITK test driver caught an exception:\n";
222 std::cerr << e.what() <<
"\n";
227 std::cerr <<
"ITK test driver caught an unknown exception!!!\n";
233 std::cerr <<
"Failed: " << testToRun <<
": No test registered with name " << testToRun <<
"\n";
240 const char *baselineImageFilename,
242 double intensityTolerance,
243 unsigned int numberOfPixelsTolerance,
244 unsigned int radiusTolerance )
253 ReaderType::Pointer baselineReader = ReaderType::New();
254 baselineReader->SetFileName(baselineImageFilename);
257 baselineReader->UpdateLargestPossibleRegion();
261 std::cerr <<
"Exception detected while reading " << baselineImageFilename <<
" : " << e.
GetDescription();
266 ReaderType::Pointer testReader = ReaderType::New();
267 testReader->SetFileName(testImageFilename);
270 testReader->UpdateLargestPossibleRegion();
274 std::cerr <<
"Exception detected while reading " << testImageFilename <<
" : " << e.
GetDescription() << std::endl;
279 ImageType::SizeType baselineSize;
280 baselineSize = baselineReader->GetOutput()->GetLargestPossibleRegion().GetSize();
281 ImageType::SizeType testSize;
282 testSize = testReader->GetOutput()->GetLargestPossibleRegion().GetSize();
284 if (baselineSize != testSize)
286 std::cerr <<
"The size of the Baseline image and Test image do not match!" << std::endl;
287 std::cerr <<
"Baseline image: " << baselineImageFilename
288 <<
" has size " << baselineSize << std::endl;
289 std::cerr <<
"Test image: " << testImageFilename
290 <<
" has size " << testSize << std::endl;
296 DiffType::Pointer diff = DiffType::New();
297 diff->SetValidInput(baselineReader->GetOutput());
298 diff->SetTestInput(testReader->GetOutput());
299 diff->SetDifferenceThreshold( intensityTolerance );
300 diff->SetToleranceRadius( radiusTolerance );
301 diff->UpdateLargestPossibleRegion();
303 unsigned long status = 0;
304 status = diff->GetNumberOfPixelsWithDifferences();
307 if ( (status > numberOfPixelsTolerance) && reportErrors )
313 OutputType::SizeType size; size.Fill(0);
315 RescaleType::Pointer rescale = RescaleType::New();
316 rescale->SetOutputMinimum(itk::NumericTraits<unsigned char>::NonpositiveMin());
317 rescale->SetOutputMaximum(itk::NumericTraits<unsigned char>::max());
318 rescale->SetInput(diff->GetOutput());
319 rescale->UpdateLargestPossibleRegion();
320 size = rescale->GetOutput()->GetLargestPossibleRegion().GetSize();
324 OutputType::IndexType index; index.Fill(0);
332 region.SetIndex(index);
334 region.SetSize(size);
336 ExtractType::Pointer extract = ExtractType::New();
337 extract->SetInput(rescale->GetOutput());
338 extract->SetExtractionRegion(region);
340 WriterType::Pointer writer = WriterType::New();
341 writer->SetInput(extract->GetOutput());
343 std::cout <<
"<DartMeasurement name=\"ImageError\" type=\"numeric/double\">";
345 std::cout <<
"</DartMeasurement>" << std::endl;
347 ::itk::OStringStream diffName;
348 diffName << testImageFilename <<
".diff.png";
351 rescale->SetInput(diff->GetOutput());
354 catch(
const std::exception& e)
356 std::cerr <<
"Error during rescale of " << diffName.str() << std::endl;
357 std::cerr << e.what() <<
"\n";
361 std::cerr <<
"Error during rescale of " << diffName.str() << std::endl;
363 writer->SetFileName(diffName.str().c_str());
368 catch(
const std::exception& e)
370 std::cerr <<
"Error during write of " << diffName.str() << std::endl;
371 std::cerr << e.what() <<
"\n";
375 std::cerr <<
"Error during write of " << diffName.str() << std::endl;
378 std::cout <<
"<DartMeasurementFile name=\"DifferenceImage\" type=\"image/png\">";
379 std::cout << diffName.str();
380 std::cout <<
"</DartMeasurementFile>" << std::endl;
382 ::itk::OStringStream baseName;
383 baseName << testImageFilename <<
".base.png";
386 rescale->SetInput(baselineReader->GetOutput());
389 catch(
const std::exception& e)
391 std::cerr <<
"Error during rescale of " << baseName.str() << std::endl;
392 std::cerr << e.what() <<
"\n";
396 std::cerr <<
"Error during rescale of " << baseName.str() << std::endl;
400 writer->SetFileName(baseName.str().c_str());
403 catch(
const std::exception& e)
405 std::cerr <<
"Error during write of " << baseName.str() << std::endl;
406 std::cerr << e.what() <<
"\n";
410 std::cerr <<
"Error during write of " << baseName.str() << std::endl;
413 std::cout <<
"<DartMeasurementFile name=\"BaselineImage\" type=\"image/png\">";
414 std::cout << baseName.str();
415 std::cout <<
"</DartMeasurementFile>" << std::endl;
417 ::itk::OStringStream testName;
418 testName << testImageFilename <<
".test.png";
421 rescale->SetInput(testReader->GetOutput());
424 catch(
const std::exception& e)
426 std::cerr <<
"Error during rescale of " << testName.str() << std::endl;
427 std::cerr << e.what() <<
"\n";
431 std::cerr <<
"Error during rescale of " << testName.str() << std::endl;
435 writer->SetFileName(testName.str().c_str());
438 catch(
const std::exception& e)
440 std::cerr <<
"Error during write of " << testName.str() << std::endl;
441 std::cerr << e.what() <<
"\n";
445 std::cerr <<
"Error during write of " << testName.str() << std::endl;
448 std::cout <<
"<DartMeasurementFile name=\"TestImage\" type=\"image/png\">";
449 std::cout << testName.str();
450 std::cout <<
"</DartMeasurementFile>" << std::endl;
454 return (status > numberOfPixelsTolerance) ? 1 : 0;
467 std::map<std::string,int> baselines;
468 baselines[std::string(baselineFilename)] = 0;
470 std::string originalBaseline(baselineFilename);
473 std::string::size_type suffixPos = originalBaseline.rfind(
".");
475 if (suffixPos != std::string::npos)
477 suffix = originalBaseline.substr(suffixPos,originalBaseline.length());
478 originalBaseline.erase(suffixPos,originalBaseline.length());
482 ::itk::OStringStream filename;
483 filename << originalBaseline <<
"." << x << suffix;
484 std::ifstream filestream(filename.str().c_str());
489 baselines[filename.str()] = 0;