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 TIGS_FIGURES_C_DEFINED
00039 #define TIGS_FIGURES_C_DEFINED
00040
00041 #include "TIGS/Figures.H"
00042
00043 #include "Image/ColorOps.H"
00044 #include "Image/CutPaste.H"
00045 #include "Image/DrawOps.H"
00046 #include "Image/Image.H"
00047 #include "Image/FilterOps.H"
00048 #include "Image/MathOps.H"
00049 #include "Image/Pixels.H"
00050 #include "Image/Range.H"
00051 #include "Image/ShapeOps.H"
00052 #include "TIGS/TigsInputFrame.H"
00053 #include "TIGS/TrainingSet.H"
00054 #include "Util/sformat.H"
00055 #include "rutz/trace.h"
00056
00057 namespace
00058 {
00059 Image<PixRGB<byte> > makeBargraph(const Image<double>& src,
00060 const float factor,
00061 const int height,
00062 int intercept,
00063 const int bar_width,
00064 const PixRGB<byte>& back,
00065 const PixRGB<byte>& fore)
00066 {
00067 GVX_TRACE(__PRETTY_FUNCTION__);
00068 Image<PixRGB<byte> > result(bar_width*src.getSize(), height, NO_INIT);
00069 result.clear(back);
00070
00071 if (intercept < 0) intercept = 0;
00072 else if (intercept >= height) intercept = height-1;
00073
00074 for (int i = 0; i < src.getSize(); ++i)
00075 {
00076 const int val = int(factor * src[i]);
00077
00078 int pos = intercept-val;
00079
00080 if (pos < 0) pos = 0;
00081 else if (pos >= height) pos = height-1;
00082
00083 drawLine(result,
00084 Point2D<int>(bar_width*i, pos),
00085 Point2D<int>(bar_width*i, intercept),
00086 fore, bar_width);
00087 }
00088
00089 return result;
00090 }
00091
00092 Image<PixRGB<byte> > addLabel(const Image<PixRGB<byte> >& img,
00093 const PixRGB<byte>& color,
00094 const char* label)
00095 {
00096 Image<PixRGB<byte> > img2(std::max(img.getWidth(), 144),
00097 img.getHeight() + 30, NO_INIT);
00098
00099 img2.clear(color);
00100
00101 inplacePaste(img2, img, Point2D<int>(0,0));
00102
00103 writeText(img2, Point2D<int>(0, img.getHeight()),
00104 label, PixRGB<byte>(0,0,0), color);
00105
00106 return img2;
00107 }
00108
00109 Image<PixRGB<byte> > stainImg(const Image<float>& img, const int zoom)
00110 {
00111 const Range<float> rr = rangeOf(img);
00112
00113 const PixRGB<float> background(5.0f, 5.0f, 5.0f);
00114 const PixRGB<float> pos_stain(100.0f, 255.0f, 150.0f);
00115 const PixRGB<float> neg_stain(255.0f, 100.0f, 100.0f);
00116
00117 return zoomXY(stainPosNeg(img,
00118 std::max(fabs(rr.max()), fabs(rr.min())),
00119 background, pos_stain, neg_stain),
00120 zoom, zoom);
00121 }
00122
00123 Point2D<int> findScaledMax(const Image<float>& img, const int zoom)
00124 {
00125 Point2D<int> loc;
00126 float maxval;
00127 findMax(img, loc, maxval);
00128 return Point2D<int>( int(zoom*(loc.i+0.5)), int(zoom*(loc.j+0.5)) );
00129 }
00130 }
00131
00132 Image<PixRGB<byte> >
00133 makeSumoDisplay(const TigsInputFrame& fin,
00134 const Image<float>& eyeposmap,
00135 const TrainingSet& tdata,
00136 const Point2D<int>& eyepos,
00137 const Image<float>& features)
00138 {
00139 GVX_TRACE("makeSumoDisplay");
00140
00141 if (fin.isGhost())
00142 LFATAL("makeSumoDisplay() needs non-ghost frames");
00143
00144 const PixRGB<byte> col_eyepos1(255, 127, 0);
00145 const PixRGB<byte> col_eyepos2(160, 160, 160);
00146 const PixRGB<byte> col_histo_back(0, 15, 15);
00147 const PixRGB<byte> col_histo_fore(0, 255, 255);
00148
00149 Image<PixRGB<byte> > drawframe(fin.origframe());
00150
00151 drawPatch(drawframe, eyepos, 3, col_eyepos1);
00152 drawCircle(drawframe, eyepos, 30, col_eyepos1, 3);
00153
00154 const int pos = tdata.p2p(eyepos);
00155
00156 ASSERT(fin.lum().getDims() == fin.rg().getDims());
00157 ASSERT(fin.rg().getDims() == fin.by().getDims());
00158
00159 const Image<PixRGB<byte> > imgs[4] =
00160 { rescale(drawframe, fin.lum().getDims()/2), decXY(fin.lum(), 2),
00161 decXY(fin.rg(), 2), decXY(fin.by(), 2) };
00162
00163 const Image<PixRGB<byte> > arr = concatArray(imgs, 4, 2);
00164
00165 Range<float> r = rangeOf(eyeposmap);
00166
00167 static Range<float> rr;
00168 rr.merge(r);
00169
00170 const PixRGB<float> background(15.0f, 15.0f, 15.0f);
00171 const PixRGB<float> pos_stain(15.0f, 255.0f, 100.0f);
00172 const PixRGB<float> neg_stain(255.0f, 15.0f, 50.0f);
00173
00174 Image<PixRGB<byte> > bbiasmap
00175 (zoomXY(stainPosNeg(eyeposmap,
00176 std::max(fabs(rr.max()), fabs(rr.min())),
00177 background, pos_stain, neg_stain),
00178 tdata.inputReduction(),
00179 tdata.inputReduction()));
00180
00181 drawPatch(bbiasmap, eyepos, 3, col_eyepos2);
00182
00183 Image<PixRGB<byte> > bbiasmap2(std::max(bbiasmap.getWidth(), 144),
00184 bbiasmap.getHeight() + 50, ZEROS);
00185
00186 inplacePaste(bbiasmap2, bbiasmap, Point2D<int>(0,0));
00187
00188 writeText(bbiasmap2, Point2D<int>(0, bbiasmap.getHeight()),
00189 sformat("min: %g (%g)", r.min(), rr.min()).c_str(),
00190 PixRGB<byte>(neg_stain), PixRGB<byte>(0,0,0));
00191
00192 writeText(bbiasmap2, Point2D<int>(0, bbiasmap.getHeight()+25),
00193 sformat("max: %g (%g)", r.max(), rr.max()).c_str(),
00194 PixRGB<byte>(pos_stain), PixRGB<byte>(0,0,0));
00195
00196 const Image<PixRGB<byte> > fhisto =
00197 makeBargraph(features, 100.0f/255.0f, 100, 100, 1,
00198 col_histo_back,
00199 col_histo_fore);
00200
00201 const Image<float> resiz_features =
00202 tdata.getFeatures().getHeight() > 1000
00203 ? decY(tdata.getFeatures(), 1 + tdata.getFeatures().getHeight() / 1000)
00204 : tdata.getFeatures();
00205
00206 const Image<PixRGB<byte> > sumo_features = concatY(fhisto, Image<PixRGB<byte> >(resiz_features));
00207
00208 const Image<PixRGB<byte> > eyehisto =
00209 makeBargraph(eyeposmap,
00210 50.f/(std::max(fabs(r.min()),
00211 fabs(r.max()))),
00212 100, 50,
00213 1,
00214 col_histo_back,
00215 col_histo_fore);
00216
00217 const Image<float> resiz_positions =
00218 tdata.getPositions().getHeight() > 1000
00219 ? decY(tdata.getPositions(), 1 + tdata.getPositions().getHeight() / 1000)
00220 : tdata.getPositions();
00221
00222 const Image<PixRGB<byte> > tp = resiz_positions * 255.0f;
00223
00224 Image<PixRGB<byte> > sumo_eyepos = concatY(eyehisto, tp);
00225
00226 drawLine(sumo_eyepos,
00227 Point2D<int>(pos, 0),
00228 Point2D<int>(pos, sumo_eyepos.getHeight()-1),
00229 col_eyepos1, 1);
00230
00231 return concatLooseX(concatLooseY(arr, bbiasmap2),
00232 concatX(sumo_features, sumo_eyepos));
00233 }
00234
00235 Image<PixRGB<byte> >
00236 makeSumoDisplay2(const TigsInputFrame& fin,
00237 const Image<float>& tdmap,
00238 const Image<float>& bumap,
00239 const Image<float>& combomap,
00240 const TrainingSet& tdata,
00241 const Point2D<int>& eyepos)
00242 {
00243 GVX_TRACE("makeSumoDisplay2");
00244
00245 if (fin.isGhost())
00246 LFATAL("makeSumoDisplay2() needs non-ghost frames");
00247
00248 const int zoom = tdata.inputReduction();
00249
00250 const Point2D<int> tdpos = findScaledMax(tdmap, zoom);
00251 const Point2D<int> bupos = findScaledMax(bumap, zoom);
00252 const Point2D<int> combopos = findScaledMax(combomap, zoom);
00253
00254 Image<PixRGB<byte> > drawframe(fin.origframe());
00255
00256 const PixRGB<byte> col_human(255, 127, 0);
00257 const PixRGB<byte> col_td(255, 64, 64);
00258 const PixRGB<byte> col_bu(64, 64, 255);
00259 const PixRGB<byte> col_combo(192, 0, 255);
00260
00261 #define DRAWPOS(img) \
00262 drawPatch(img, tdpos, 3, col_td); \
00263 drawCircle(img, tdpos, 18, col_td, 3); \
00264 drawPatch(img, bupos, 3, col_bu); \
00265 drawCircle(img, bupos, 18, col_bu, 3); \
00266 drawPatch(img, combopos, 3, col_combo); \
00267 drawCircle(img, combopos, 18, col_combo, 3); \
00268 drawPatch(img, eyepos, 3, col_human); \
00269 drawCircle(img, eyepos, 30, col_human, 3)
00270
00271 DRAWPOS(drawframe);
00272
00273 Image<PixRGB<byte> > btdmap = stainImg(tdmap, zoom);
00274 DRAWPOS(btdmap);
00275
00276 Image<PixRGB<byte> > bbumap = stainImg(bumap, zoom);
00277 DRAWPOS(bbumap);
00278
00279 Image<PixRGB<byte> > bcombomap = stainImg(combomap, zoom);
00280 DRAWPOS(bcombomap);
00281
00282 #undef DRAWPOS
00283
00284 return concatLooseY
00285 (concatLooseX(addLabel(decXY(lowPass3(drawframe)), col_human, "input"),
00286 addLabel(decXY(lowPass3(btdmap)), col_td, "top-down")),
00287 concatLooseX(addLabel(decXY(lowPass3(bbumap)), col_bu, "bottom-up"),
00288 addLabel(decXY(lowPass3(bcombomap)), col_combo, "bu*td combo")));
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298 #endif // TIGS_FIGURES_C_DEFINED