DGtalTools 2.0.0
Loading...
Searching...
No Matches
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
49using namespace std;
50using namespace DGtal;
52
53typedef ImageContainerBySTLVector < Z2i::Domain, unsigned char > Image2D;
54typedef ImageContainerBySTLVector < Z2i::Domain, unsigned int > Image2DErr;
55typedef GradientColorMap<unsigned int, CMAP_JET, 1 > JetMap;
56
57
58
106Statistic< int>
107getMAEstats(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
124Statistic< int>
125getMSEstats(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
144template<typename StatisticT>
145void
146displayStats(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
154int 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
Definition ATu0v1.h:57