DGtalTools  1.5.beta
2dCompImage.cpp
1 
31 #include "DGtal/base/Common.h"
32 #include "DGtal/helpers/StdDefs.h"
33 #include <DGtal/io/readers/GenericReader.h>
34 #include <DGtal/io/writers/GenericWriter.h>
35 
36 
37 #include <DGtal/images/Image.h>
38 #include <DGtal/images/ImageContainerBySTLVector.h>
39 #include <DGtal/images/imagesSetsUtils/SetFromImage.h>
40 #include <DGtal/io/writers/PPMWriter.h>
41 #include <DGtal/math/Statistic.h>
42 #include "DGtal/io/colormaps/GradientColorMap.h"
43 #include <DGtal/math/Statistic.h>
44 
45 #include "CLI11.hpp"
46 
47 
49 using namespace std;
50 using namespace DGtal;
52 
56 
57 
58 
107 getMAEstats(const Image2D & imageA, const Image2D &imageB, Image2DErr &imageMAE)
108 {
109  Statistic< int> stat(false);
110  for(auto const &point: imageA.domain())
111  {
112  unsigned int error = abs((imageA(point)-imageB(point)));
113  stat.addValue(error);
114  imageMAE.setValue(point, error);
115  }
116  stat.terminate();
117  return stat;
118 }
119 
120 
125 getMSEstats(const Image2D & imageA, const Image2D &imageB, Image2DErr &imageMSE)
126 {
127  Statistic< int> stat(false);
128  for(Image2D::Domain::ConstIterator it = imageA.domain().begin();
129  it!=imageA.domain().end(); it++)
130  {
131  int error = (imageA(*it)-imageB(*it))*(imageA(*it)-imageB(*it));
132  stat.addValue(error);
133  imageMSE.setValue(*it, error);
134  }
135  stat.terminate();
136  return stat;
137 }
138 
139 
140 
144 template<typename StatisticT>
145 void
146 displayStats(const StatisticT &aStat, const string &type)
147 {
148  std::cout << "# Stats on " << type << ": mean max min unbiased_variance nb_samples " << std::endl;
149  std::cout << aStat.mean() << " " << aStat.max() << " " << aStat.min() << " "
150  << " " << aStat.unbiasedVariance() << " " << aStat.samples() << std::endl;
151 }
152 
153 
154 int main( int argc, char** argv )
155 {
156 
157  // parse command line using CLI ----------------------------------------------
158  CLI::App app;
159  std::string inputFileNameA;
160  std::string inputFileNameB;
161  std::string basenameOutput;
162  int maxValueMAE;
163  int maxValueMSE;
164 
165  app.description("Compare images and displays differences (squared and absolute differences).\n Typical use example:\n \t 2dCompImage imageA.pgm imageB.pgm -e errorImage -S 100 \n");
166  app.add_option("-a,--imageA,1", inputFileNameA, "Input filename of image A." )
167  ->required()
168  ->check(CLI::ExistingFile);
169  app.add_option("-b,--imageB,2", inputFileNameA, "Input filename of image B." )
170  ->required()
171  ->check(CLI::ExistingFile);
172 
173 
174  app.add_option("--imageError,-e",basenameOutput, "Output error image basename (will generate two images <basename>MSE.ppm and <basename>MAE.ppm).");
175 
176  auto setMaxMSEOpt = app.add_option("--setMaxColorValueMSE,-S",maxValueMSE, "Set the maximal color value for the scale display of MSE (else the scale is set the maximal MSE value).");
177  auto setMaxMAEOpt = app.add_option("--setMaxColorValueMAE,-A",maxValueMAE, "Set the maximal color value for the scale display of MAE (else the scale is set from the maximal MAE value).");
178 
179 
180  app.get_formatter()->column_width(40);
181  CLI11_PARSE(app, argc, argv);
182  // END parse command line using CLI ----------------------------------------------
183 
184 
185  // Input images ----------------------------------------------------
186  Image2D imageA = GenericReader<Image2D>::import(inputFileNameA);
187  Image2D imageB = GenericReader<Image2D>::import(inputFileNameB);
188 
189  Image2DErr imageErr (imageA.domain());
190 
191 
192  // Absolute Error between imageA and imageB -------------------------
193  Statistic<int> statMA = getMAEstats(imageA, imageB, imageErr);
194  int maxVal = statMA.max();
195  if(setMaxMAEOpt->count() > 0)
196  {
197  maxVal = maxValueMAE;
198  }
199  JetMap jmapMA(0, maxVal);
200  displayStats(statMA, "Absolute errror");
201  stringstream maeName; maeName << basenameOutput;
202  maeName << "MAE.ppm";
203  PPMWriter<Image2DErr, JetMap>::exportPPM(maeName.str(), imageErr, jmapMA);
204 
205  // Squared Error between imageA and imageB -------------------------
206  Statistic<int> statSE = getMSEstats(imageA, imageB, imageErr);
207  maxVal = statMA.max();
208  if(setMaxMSEOpt->count()>0)
209  {
210  maxVal = maxValueMSE;
211  }
212  JetMap jmapSE(0, maxVal);
213  displayStats(statSE, "Squared error");
214  stringstream mseName; mseName << basenameOutput;
215  mseName << "MSE.ppm";
216  PPMWriter<Image2DErr, JetMap>::exportPPM(mseName.str(), imageErr, jmapSE);
217 
218  return 0;
219 }
220 
int main(int argc, char **argv)
const Domain & domain() const
void setValue(const Point &aPoint, const Value &aValue)
std::vector< Value >::const_iterator ConstIterator
Quantity max() const
T abs(const T &a)
MessageStream error