00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef TRANSPORT_STATSOUTPUTSERIES_C_DEFINED
00039 #define TRANSPORT_STATSOUTPUTSERIES_C_DEFINED
00040
00041 #include "Transport/StatsOutputSeries.H"
00042
00043 #include "Image/ColorOps.H"
00044 #include "Image/Image.H"
00045 #include "Image/MathOps.H"
00046 #include "Image/Pixels.H"
00047 #include "Image/Range.H"
00048 #include "Raster/GenericFrame.H"
00049 #include "Util/FileUtil.H"
00050
00051 #include <cstdio>
00052
00053 template <class T>
00054 Range<T> getRange(const Image<T>& x)
00055 {
00056 Range<T> result;
00057 for (typename Image<T>::const_iterator
00058 itr = x.begin(), stop = x.end(); itr != stop; ++itr)
00059 result.merge(*itr);
00060 return result;
00061 }
00062
00063 struct StatsOutputSeries::Impl
00064 {
00065 Impl()
00066 :
00067 fileName(""),
00068 fileOwned(true),
00069 frameNumber(-1),
00070 file(0),
00071 meanR(0.0),
00072 meanG(0.0),
00073 meanB(0.0),
00074 count(0)
00075 {}
00076
00077 ~Impl()
00078 {
00079 if (this->file != 0)
00080 {
00081 fflush(this->file);
00082
00083
00084
00085 if (this->fileOwned)
00086 fclose(this->file);
00087 }
00088 }
00089
00090 void openFile()
00091 {
00092 if (this->file == 0)
00093 {
00094 this->file = stdOutputFileOpen(this->fileName,
00095 &this->fileOwned);
00096
00097
00098 ASSERT(this->file != 0);
00099 }
00100 }
00101
00102 void printStatsRGB(const Image<PixRGB<byte> >& img,
00103 const std::string& imgname, const std::string& imgtype)
00104 {
00105 this->openFile();
00106
00107 Image<byte> r, g, b;
00108 getComponents(img, r, g, b);
00109
00110 const double mean_r = mean(r);
00111 const double stdev_r = stdev(r);
00112 const Range<byte> range_r = getRange(r);
00113
00114 const double mean_g = mean(g);
00115 const double stdev_g = stdev(g);
00116 const Range<byte> range_g = getRange(g);
00117
00118 const double mean_b = mean(b);
00119 const double stdev_b = stdev(b);
00120 const Range<byte> range_b = getRange(b);
00121
00122 fprintf(this->file,
00123 "%06d "
00124 "R=[%d .. %f +/- %f .. %d] "
00125 "G=[%d .. %f +/- %f .. %d] "
00126 "B=[%d .. %f +/- %f .. %d] %% %s (%dx%d %s)\n",
00127 this->frameNumber,
00128 int(range_r.min()), mean_r, stdev_r, int(range_r.max()),
00129 int(range_g.min()), mean_g, stdev_g, int(range_g.max()),
00130 int(range_b.min()), mean_b, stdev_b, int(range_b.max()),
00131 imgname.c_str(), img.getWidth(), img.getHeight(),
00132 imgtype.c_str());
00133 fflush(this->file);
00134
00135 this->rangeR.merge(range_r);
00136 this->rangeG.merge(range_g);
00137 this->rangeB.merge(range_b);
00138
00139 this->meanR += mean_r;
00140 this->meanG += mean_g;
00141 this->meanB += mean_b;
00142 ++(this->count);
00143 }
00144
00145 void printStatsSummary()
00146 {
00147 this->openFile();
00148
00149 fprintf(this->file,
00150 "OVERALL "
00151 "R=[%d .. %f .. %d] "
00152 "G=[%d .. %f .. %d] "
00153 "B=[%d .. %f .. %d] %% summary of %d frames\n",
00154 int(rangeR.min()), meanR/count, int(rangeR.max()),
00155 int(rangeG.min()), meanG/count, int(rangeG.max()),
00156 int(rangeB.min()), meanB/count, int(rangeB.max()),
00157 count);
00158 fflush(this->file);
00159 }
00160
00161 std::string fileName;
00162 bool fileOwned;
00163 int frameNumber;
00164 FILE* file;
00165
00166 Range<byte> rangeR;
00167 Range<byte> rangeG;
00168 Range<byte> rangeB;
00169 double meanR;
00170 double meanG;
00171 double meanB;
00172 int count;
00173 };
00174
00175
00176 StatsOutputSeries::StatsOutputSeries(OptionManager& mgr)
00177 :
00178 FrameOstream(mgr, "Stats Output Series", "StatsOutputSeries"),
00179 rep(new Impl)
00180 {}
00181
00182
00183 StatsOutputSeries::~StatsOutputSeries()
00184 {
00185 delete rep;
00186 }
00187
00188
00189 void StatsOutputSeries::setConfigInfo(const std::string& filename)
00190 {
00191
00192
00193
00194
00195 this->setFileName(filename);
00196 }
00197
00198
00199 bool StatsOutputSeries::setFrameNumber(int n)
00200 {
00201 rep->frameNumber = n;
00202
00203 return true;
00204 }
00205
00206
00207 void StatsOutputSeries::writeFrame(const GenericFrame& f,
00208 const std::string& shortname,
00209 const FrameInfo& auxinfo)
00210 {
00211 const std::string nm = shortname;
00212 const std::string tp = f.nativeTypeName();
00213
00214 switch (f.nativeType())
00215 {
00216 case GenericFrame::NONE: break;
00217 case GenericFrame::RGB_U8: rep->printStatsRGB(f.asRgbU8(),nm,tp); break;
00218 case GenericFrame::RGBD: rep->printStatsRGB(f.asRgbU8(),nm,tp); break;
00219 case GenericFrame::RGB_F32: rep->printStatsRGB(f.asRgbU8(),nm,tp); break;
00220 case GenericFrame::GRAY_U8: rep->printStatsRGB(f.asRgbU8(),nm,tp); break;
00221 case GenericFrame::GRAY_F32:rep->printStatsRGB(f.asRgbU8(),nm,tp); break;
00222 case GenericFrame::VIDEO: rep->printStatsRGB(f.asRgbU8(),nm,tp); break;
00223 case GenericFrame::RGB_U16: break;
00224 case GenericFrame::GRAY_U16: break;
00225 }
00226 }
00227
00228
00229 void StatsOutputSeries::closeStream(const std::string& shortname)
00230 {
00231
00232 }
00233
00234
00235 void StatsOutputSeries::setFileName(const std::string& s)
00236 {
00237 if (rep->file != 0)
00238 LFATAL("can't change filename while output file is already open");
00239
00240 rep->fileName = s;
00241 }
00242
00243
00244 void StatsOutputSeries::stop2()
00245 {
00246 rep->printStatsSummary();
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256 #endif // TRANSPORT_STATSOUTPUTSERIES_C_DEFINED