DGtalTools  0.9.4
volImageMetrics.cpp
1 
69 #include <iostream>
70 #include <DGtal/base/Common.h>
71 #include <DGtal/io/readers/GenericReader.h>
72 #include <DGtal/io/writers/GenericWriter.h>
73 #include <DGtal/helpers/StdDefs.h>
74 #include <DGtal/images/Image.h>
75 #include <DGtal/images/ImageContainerBySTLVector.h>
76 #include <DGtal/images/imagesSetsUtils/SetFromImage.h>
77 #include <DGtal/math/Statistic.h>
78 
79 #include <boost/program_options/options_description.hpp>
80 #include <boost/program_options/parsers.hpp>
81 #include <boost/program_options/variables_map.hpp>
82 #include <limits>
83 
84 
85 using namespace std;
86 using namespace DGtal;
87 using namespace Z3i;
88 
89 namespace po = boost::program_options;
90 
93 
94 
95 double
96 getRMSE(const Image3D & imageA, const Image3D &imageB){
97  double sumDiff=0;
98  for(Image3D::Domain::ConstIterator it = imageA.domain().begin(); it!=imageA.domain().end(); it++){
99  sumDiff+=(imageA(*it)-imageB(*it))*(imageA(*it)-imageB(*it));
100  }
101  return sqrt(sumDiff/imageA.domain().size());
102 }
103 
104 
105 double
106 getPSNR(const Image3D & imageA, const Image3D &imageB, double rmsd){
107  unsigned long long int d = std::numeric_limits<Image3D::Value>::max();
108  return 10.0*log10(d*d/rmsd);
109 }
110 
111 
112 
113 
114 int main(int argc, char**argv)
115 {
116 
117  po::options_description general_opt ( "Allowed options are: " );
118  general_opt.add_options()
119  ( "help,h", "display this message." )
120  ( "volA,a", po::value<std::string>(), "Input filename of volume A (vol format, and other pgm3d can also be used)." )
121  ( "volB,b", po::value<std::string>(), "Input filename of volume B (vol format, and other pgm3d can also be used)." );
122 
123  bool parseOK=true;
124  po::variables_map vm;
125  try{
126  po::store(po::parse_command_line(argc, argv, general_opt), vm);
127  }catch(const std::exception& ex){
128  parseOK=false;
129  trace.info()<< "Error checking program options: "<< ex.what()<< endl;
130  }
131  po::notify(vm);
132 
133  if ( !parseOK || vm.count ( "help" ) || ! vm.count("volA")||! vm.count("volB") )
134  {
135  trace.info() << "Apply basic image measures (RMSE, PSNR) between two volumetric images A and B."<<std::endl
136  << std::endl << "Basic usage: "<<std::endl
137  << "\t volImageMetrics --volA <volAFilename> --volB <volBFilename> "<<std::endl
138  << general_opt << "\n"
139  << "Typical use :\n volImageMetrics -a imageA.vol -b imageB.vol \n" ;
140 
141  return 0;
142  }
143 
144  if(! vm.count("volA")||! vm.count("volB"))
145  {
146  trace.error() << " The two volume filename are needed to be defined" << endl;
147  return 0;
148  }
149 
150  std::string volAFilename = vm["volA"].as<std::string>();
151  std::string volBFilename = vm["volB"].as<std::string>();
152 
153  Image3D imageA = GenericReader<Image3D>::import(volAFilename);
154  Image3D imageB = GenericReader<Image3D>::import(volBFilename);
155 
156 
157  std::cout << "# Image based measures (generated with volImageMetrics) given with the image A: "<< volAFilename<< " and the image B: "<< volBFilename << endl;
158  std::cout << "# RMSE PSNR "<< endl;
159 
160  double rmse= getRMSE(imageA, imageB);
161  double psnr= getPSNR(imageA, imageB, rmse);
162 
163  std::cout << " " << rmse << " " << psnr << endl;
164 
165  return 1;
166 }
167 
STL namespace.
Trace trace(traceWriterTerm)
std::ostream & info()
const Domain & domain() const
std::vector< Value >::const_iterator ConstIterator
std::ostream & error()