libeblearngui
/home/rex/ebltrunk/tools/libeblearngui/include/detector_gui.hpp
00001 /***************************************************************************
00002  *   Copyright (C) 2009 by Pierre Sermanet   *
00003  *   pierre.sermanet@gmail.com   *
00004  *   All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Redistribution under a license not approved by the Open Source
00014  *       Initiative (http://www.opensource.org) must display the
00015  *       following acknowledgement in all advertising material:
00016  *        This product includes software developed at the Courant
00017  *        Institute of Mathematical Sciences (http://cims.nyu.edu).
00018  *     * The names of the authors may not be used to endorse or promote products
00019  *       derived from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
00022  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00023  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00024  * DISCLAIMED. IN NO EVENT SHALL ThE AUTHORS BE LIABLE FOR ANY
00025  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00028  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  ***************************************************************************/
00032 
00033 #ifndef DETECTOR_GUI_HPP_
00034 #define DETECTOR_GUI_HPP_
00035 
00036 using namespace std;
00037 
00038 #include <deque>
00039 
00040 namespace ebl {
00041 
00043   // detector_gui
00044 
00045   template <typename T, class Tstate>
00046   detector_gui<T,Tstate>::
00047   detector_gui(uint draw_extracted_,
00048                bool show_detqueue_, uint step_, uint qheight_,
00049                uint qwidth_, bool show_detqueue2_, uint step2_,
00050                uint qheight2_, uint qwidth2_, bool show_class_, bool show_conf_)
00051     : display_wid(-1), display_wid_fprop(-1), display_wid_gt(-1),
00052       draw_extracted(draw_extracted_),
00053       show_detqueue(show_detqueue_), show_detqueue2(show_detqueue2_),
00054       step(step_), step2(step2_), qheight(qheight_), qwidth(qwidth_),
00055       qheight2(qheight2_), qwidth2(qwidth2_), detcnt(0),
00056       show_class(show_class_), show_conf(show_conf_) {
00057     cout << "detector_gui: " << (draw_extracted > 0 ? "" : "not ")
00058          << "showing extracted windows." << endl;
00059   }
00060 
00061   template <typename T, class Tstate>
00062   detector_gui<T,Tstate>::~detector_gui() {
00063   }
00064 
00065   template <typename T, class Tstate> template <typename Tin>
00066   bboxes& detector_gui<T,Tstate>::
00067   display(detector<T,Tstate> &cl, idx<Tin> &img, double threshold,
00068           const char *frame_name, uint h0, uint w0, double dzoom,  T vmin,
00069           T vmax, int wid, const char *wname, float transparency) {
00070     display_wid = (wid >= 0) ? wid :
00071       new_window((wname ? wname : "detector"));
00072     select_window(display_wid);
00073 
00074     // run network
00075     bboxes& vb = cl.fprop(img, frame_name);
00076     display_minimal(img, vb, cl.labels, h0, w0, dzoom, vmin, vmax, display_wid,
00077                     false, transparency, show_class, show_conf);
00078     // draw masks class
00079     if (!mask_class.empty()) {
00080       idx<T> mask = cl.get_mask(mask_class);
00081       draw_mask(mask, h0, w0, dzoom, dzoom,
00082                 255, 0, 0, 127, mask_threshold);
00083     }
00084     return vb;
00085   }
00086 
00087   template <typename T, class Tstate> template <typename Tin>
00088   void detector_gui<T,Tstate>::
00089   display_minimal(idx<Tin> &img, bboxes& vb, vector<string> &labels, uint &h0,
00090                   uint &w0, double dzoom,  T vmin, T vmax, int wid,
00091                   bool show_parts, float transparency, bool show_class,
00092                   bool show_conf, bboxes *bb2) {
00093     // draw image
00094     draw_matrix(img, h0, w0, dzoom, dzoom, (Tin)vmin, (Tin)vmax);
00095     // draw bboxes (in reverse order to display best on top)
00096     for (int i = vb.size() - 1; i >= 0; --i) {
00097       bbox &bb = vb[(uint) i];
00098       // // draw parts
00099       // if (show_parts && dynamic_cast<bbox_parts&>(bb))
00100       //        draw_bbox_parts(((bbox_parts&) bb), labels, h0, w0, dzoom);
00101       // draw box
00102       draw_bbox(bb, labels, h0, w0, dzoom, transparency, true, 0, show_class,
00103                 show_conf);
00104     }
00105     if (bb2) {
00106       for (int i = bb2->size() - 1; i >= 0; --i) {
00107         bbox &bb = (*bb2)[(uint) i];
00108         draw_bbox(bb, labels, h0, w0, dzoom, transparency, true, 1, show_class,
00109                   show_conf);
00110       }
00111     }
00112     h0 += img.dim(0) + 5;
00113   }
00114 
00115   template <typename T, class Tstate> template <typename Tin>
00116   bboxes& detector_gui<T,Tstate>::
00117   display_input(detector<T,Tstate> &cl, idx<Tin> &img, double threshold,
00118                 const char *frame_name, uint h0, uint w0, double dzoom, T vmin,
00119                 T vmax, int wid, const char *wname, float transparency) {
00120     display_wid = (wid >= 0) ? wid :
00121       new_window((wname ? wname : "detector: output"));
00122     select_window(display_wid);
00123     //    disable_window_updates();
00124     bboxes &bb = display(cl, img, threshold, frame_name, h0, w0, dzoom, vmin,
00125                          vmax, wid, wname, transparency);
00126     uint w = w0 + (uint) (img.dim(1) * dzoom + 5);
00127     // draw input
00128     draw_matrix(img, "input", h0, w, dzoom, dzoom, (Tin) vmin, (Tin) vmax);
00129     return bb;
00130   }
00131 
00132   template <typename T, class Tstate> template <typename Tin>
00133   void detector_gui<T,Tstate>::
00134   display_groundtruth(detector<T,Tstate> &cl, idx<Tin> &img,
00135                       bboxes &groundtruth, bboxes &filtered,
00136                       bboxes &nonfiltered, bboxes &pos,
00137                       bboxes &neg, svector<midx<T> > &pp_pos,
00138                       svector<midx<T> > &pp_neg,
00139                       uint h0, uint w0, double dzoom, T vmin, T vmax, int wid) {
00140     if (wid >= 0) display_wid_gt = wid;
00141     else if (display_wid_gt < 0)
00142       display_wid_gt = new_window("detector: groundtruth");
00143     select_window(display_wid_gt);
00144     disable_window_updates();
00145     clear_window();
00146     night_mode();
00147     uint w = w0, h = h0;
00148     // draw image
00149     draw_matrix(img, "all groundtruth", h, w, dzoom, dzoom);
00150     // draw all groundtruth boxes
00151     for (uint i = 0; i < groundtruth.size(); ++i) {
00152       bbox &gt = groundtruth[i];
00153       draw_bbox(gt, cl.labels, h, w, dzoom, 0, true, 3, false, false);
00154     }
00155     w += (uint) (img.dim(1) * dzoom + 5);
00156     // draw image
00157     draw_matrix(img, "positive bootstrapping", h, w, dzoom, dzoom);
00158     // draw filtered groundtruth boxes
00159     for (uint i = 0; i < filtered.size(); ++i) {
00160       bbox &gt = filtered[i];
00161       draw_bbox(gt, cl.labels, h, w, dzoom, 0, true, 5, false, false);
00162     }
00163     // draw gt-matched positives
00164     for (uint i = 0; i < pos.size(); ++i) {
00165       bbox &p = pos[i];
00166       draw_bbox(p, cl.labels, h, w, dzoom, 0, true, 6, false, false);
00167     }
00168     w += (uint) (img.dim(1) * dzoom + 5);
00169     // draw image
00170     draw_matrix(img, "negative bootstrapping", h, w, dzoom, dzoom);
00171     // draw filtered boxes
00172     for (uint i = 0; i < filtered.size(); ++i) {
00173       bbox &gt = filtered[i];
00174       draw_bbox(gt, cl.labels, h, w, dzoom, 0, true, 5, false, false);
00175     }
00176     // draw non-filtered boxes
00177     for (uint i = 0; i < nonfiltered.size(); ++i) {
00178       bbox &gt = nonfiltered[i];
00179       draw_bbox(gt, cl.labels, h, w, dzoom, 0, true, 3, false, false);
00180     }
00181     // draw negatives
00182     for (uint i = 0; i < neg.size(); ++i) {
00183       bbox &p = neg[i];
00184       draw_bbox(p, cl.labels, h, w, dzoom, 0, true, 7, false, false);
00185     }
00186     // draw positive preprocessed bootstrappings
00187     w = w0;
00188     h += (uint) (img.dim(0) * dzoom + 5);
00189     display_preprocessed(pp_pos, pos, cl.labels, h, w, dzoom, vmin, vmax);
00190     // draw positive preprocessed bootstrappings
00191     w = w0;
00192     display_preprocessed(pp_neg, neg, cl.labels, h, w, dzoom, vmin, vmax);
00193     enable_window_updates();
00194   }
00195 
00196   template <typename T, class Tstate> template <typename Tin>
00197   bboxes& detector_gui<T,Tstate>::
00198   display_inputs_outputs(detector<T,Tstate> &cl, idx<Tin> &img,
00199                          double threshold, const char *frame_name,
00200                          uint h0, uint w0, double dzoom,
00201                          T vmin, T vmax, int wid, const char *wname,
00202                          T in_vmin, T in_vmax, float transparency, uint wmax) {
00203     display_wid_fprop = (wid >= 0) ? wid :
00204       new_window((wname ? wname : "detector: inputs, outputs & internals"));
00205     select_window(display_wid_fprop);
00206 
00207     // draw input and output
00208     bboxes& bb =
00209       display_input(cl, img, threshold, frame_name,
00210                     h0, w0, dzoom, in_vmin, in_vmax, display_wid_fprop, wname,
00211                     transparency);
00212     // compute min and max of all outputs, to maximize intensity display range
00213     bool first_time = true;
00214     if (vmin == vmax) {
00215       for (uint i = 0; i < cl.outputs.size(); ++i) {
00216         mstate<Tstate> &o = cl.outputs[i];
00217         for (typename mstate<Tstate>::iterator j = o.begin();
00218              j != o.end(); ++j) {
00219           idx<T> outx = j->x;
00220           if (first_time) {
00221             vmin = idx_min(outx);
00222             vmax = idx_max(outx);
00223             first_time = false;
00224           } else {
00225             vmin = MIN(vmin, idx_min(outx));
00226             vmax = std::max(vmax, idx_max(outx));
00227           }
00228         }
00229       }
00230     }
00231     EDEBUG("Displaying outputs in range [" << vmin << ", " << vmax
00232           << "], outputs actual range is [" << idx_min(cl.outputs[0][0].x)
00233           << ", " << idx_max(cl.outputs[0][0].x) << "]");
00234     h0 += (uint) (cl.indim.dim(1) * dzoom + 20);
00235     // draw extracted windows
00236     if (draw_extracted == 1) { // preprocessed
00237       bboxes bbs;
00238       // display all preprocessed
00239       svector<midx<T> >& pp = cl.get_preprocessed(bbs);
00240       display_preprocessed(pp, bbs, cl.labels, h0, w0, dzoom, vmin, vmax, wmax);
00241       // display diverse preprocessed when saving
00242       if (cl.save_mode > 0 || cl.diverse_ordering) {
00243         svector<midx<T> >& fpp =
00244           cl.get_preprocessed(bbs, cl.save_max_per_frame, cl.diverse_ordering);
00245         display_preprocessed(fpp, bbs, cl.labels, h0, w0, dzoom, vmin, vmax,
00246                              wmax);
00247       }
00248     }
00249     else if (draw_extracted == 2) { // originals
00250       vector<idx<T> >& pp = cl.get_originals();
00251       idx<T> m;
00252       if (pp.size() > 0) {
00253         m = pp[0];
00254         h0 += 15 * 3;
00255         uint wpp = w0, hpp = h0;
00256         gui << white_on_transparent() << at(h0 - 15 * 4, w0) << pp.size()
00257             << " positive windows with dimensions " << m;
00258         ostringstream o;
00259         o.precision(3);
00260         for (uint i = 0; i < pp.size() && wpp < 5000; ++i) {
00261           hpp = h0;
00262           m = pp[i];
00263           bbox &b = bb[i];
00264           // print bbox infos
00265           o.str(""); o << b.confidence; gui << at(hpp - 15 * 3, wpp) << o.str();
00266           gui << at(hpp - 15 * 2, wpp) << b.iscale_index;
00267           gui << at(hpp - 15 * 1, wpp) << ((uint)b.class_id < cl.labels.size() ?
00268                                            cl.labels[b.class_id].c_str():"***");
00269           m = m.shift_dim(0, 2);
00270           draw_matrix(m, hpp, wpp, dzoom, dzoom, (T)0, (T)255);
00271           hpp += m.dim(0) + 1;
00272           wpp += m.dim(1) + 2;
00273         }
00274         h0 = hpp + 20;
00275       }
00276     }
00277     // display input states
00278     uint htmp = h0;
00279     display_inputs(cl, h0, w0, bb, dzoom, vmin, vmax, transparency);
00280     h0 = htmp;
00281     w0 += 20;
00282     // display output states
00283     display_outputs(cl, h0, w0, bb, dzoom, vmin, vmax, transparency);
00284 
00285     // display queues of detections
00286     if (show_detqueue || show_detqueue2) {
00287       uint hh0 = h0;
00288       vector<idx<T> > &new_detections = cl.get_originals();
00289       if (show_detqueue)
00290         update_and_display_queue(detqueue, step, qheight, qwidth,
00291                                  new_detections, detcnt, hh0, w0, dzoom);
00292       if (show_detqueue2)
00293         update_and_display_queue(detqueue2, step2, qheight2, qwidth2,
00294                                  new_detections, detcnt, hh0, w0, dzoom);
00295       detcnt += new_detections.size();
00296     }
00297     // reactive window drawing
00298     enable_window_updates();
00299     return bb;
00300   }
00301 
00302   template <typename T, class Tstate> void detector_gui<T,Tstate>::
00303   display_inputs(detector<T,Tstate> &cl, uint &h0, uint &w0, bboxes &bb,
00304                  double dzoom, T vmin, T vmax, float transparency) {
00305     int scale = 0;
00306     uint wmax = 0;
00307     ostringstream s;
00308     // display all outputs
00309     mstate<Tstate> &ins = cl.ppinputs[0];
00310     for (uint i = 0; i < ins.size(); ++i) {
00311       Tstate &t = ins[i];
00312       // draw inputs
00313       string ss;
00314       ss << "scale #" << scale;
00315       int htmp = h0;
00316       ss << " " << t.x.dim(1) << "x" << t.x.dim(2);
00317       idx<T> tx = t.x.shift_dim(0, 2);
00318       draw_matrix(tx, htmp, w0, dzoom, dzoom, (T)vmin, (T)vmax);
00319       wmax = std::max(wmax, (uint) (w0 + tx.dim(1)));
00320       // // loop on all boxes of this scale and this state#
00321       // for (bboxes::iterator q = bb.begin(); q != bb.end(); ++q) {
00322       //        bbox &b = *q;
00323       //        if (scale == b.iscale_index) {
00324       //          // if (i >= b.mi.size()) eblerror("expected as many states as boxes");
00325       //          // rect<float> r(htmp + b.mi[i].h0, w0 + b.mi[i].w0,
00326       //          //            b.mi[i].height, b.mi[i].width);
00327       //          rect<float> r(htmp + b.mi[0].h0, w0 + b.mi[0].w0,
00328       //                        b.mi[0].height, b.mi[0].width);
00329       //          draw_box(r, 0, 0, 255);
00330       //          draw_cross(r.hcenter(), r.wcenter(), 3, 0, 0, 255, 255);
00331       //        }
00332       //        htmp += t.x.dim(1) + states_separation;
00333       // }
00334 
00335       gui << white_on_transparent() << at(h0 - 18, w0) << ss;
00336       // draw bboxes on scaled input
00337       if (!cl.bboxes_off) {
00338         for (bboxes::iterator ibb = bb.begin(); ibb != bb.end(); ++ibb) {
00339           if (scale == ibb->iscale_index)
00340             draw_bbox(*ibb, cl.labels, h0, w0, dzoom, transparency, false, 0,
00341                       show_class, show_conf);
00342           // draw all sub boxes
00343           for (bboxes::iterator jbb = ibb->children.begin();
00344                jbb != ibb->children.end(); ++jbb) {
00345             if (scale == jbb->iscale_index)
00346               draw_bbox(*jbb, cl.labels, h0, w0, dzoom, transparency, false, 1,
00347                         show_class, show_conf);
00348           }
00349         }
00350       }
00351       scale++;
00352       h0 += (uint) (t.x.dim(1) * dzoom + 20);
00353     }
00354     w0 = wmax;
00355   }
00356 
00357 
00358   template <typename T, class Tstate> void detector_gui<T,Tstate>::
00359   display_outputs(detector<T,Tstate> &cl, uint &h0, uint &w0, bboxes &bb,
00360                   double dzoom, T vmin, T vmax, float transparency) {
00361     uint h = h0, maxw = 0;
00362     uint color = 0;
00363     // draw answers
00364     for (uint k = 0; k < cl.answers.size(); ++k) {
00365       double czoom = dzoom;// * 2.0;
00366       Tstate &o = cl.answers[k];
00367 
00368       //uint lab = 0;
00369       idx<T> out0 = o.x.select(0, 0);
00370       idx<T> out1 = o.x.select(0, 1);
00371       string s;
00372       uint w = w0;
00373       s << "classes " << out0.dim(0) << "x" << out0.dim(1);
00374       gui << at((uint) (h - 20), (uint) w) << white_on_transparent() << s;
00375       draw_matrix(out0, h, w, czoom, czoom, idx_min(out0), idx_max(out0));
00376       // // draw crosses for found boxes
00377       // for (bboxes::iterator i = bb.begin(); i != bb.end(); ++i) {
00378       //        color = 0;
00379       //        if (k == (uint) i->oscale_index && (uint) i->class_id == lab)
00380       //          draw_cross(i->o.h0 * czoom + h0, i->o.w0 * czoom + w, 3,
00381       //                     color_list[color][0], color_list[color][1],
00382       //                     color_list[color][2]);
00383       w += (uint) (out0.dim(1) * czoom + 10);
00384       s = "";
00385       s << "conf " << out0.dim(0) << "x" << out0.dim(1);
00386       gui << at((uint) (h - 20), (uint) w) << white_on_transparent() << s;
00387       draw_matrix(out1, h, w, czoom, czoom, (T) 0, (T) 1);
00388       h += (uint) (out0.dim(0) * czoom + 20);
00389       w += (uint) (out0.dim(1) * czoom + 10);
00390       if (w > maxw) maxw = w;
00391     }
00392     w0 = maxw;
00393     // draw outputs
00394     mstate<Tstate> &oo = cl.outputs[0];
00395     for (uint k = 0; k < oo.size(); ++k) {
00396       double czoom = dzoom;// * 2.0;
00397       Tstate &o = oo[k];
00398       uint lab = 0;
00399       idx<T> outx = o.x;
00400       uint w = w0;
00401       { idx_bloop1(category, outx, T) {
00402           string s;
00403           if (lab < cl.labels.size()) s << cl.labels[lab] << " ";
00404           else s << "feature " << lab << " ";
00405           s << category.dim(0) << "x" << category.dim(1);
00406           gui << at((uint) (h0 - 20), (uint) w) << white_on_transparent() << s;
00407           draw_matrix(category, h0, w, czoom, czoom, vmin, vmax);
00408           // draw crosses for found boxes
00409           for (bboxes::iterator i = bb.begin(); i != bb.end(); ++i) {
00410             color = 0;
00411             if (k == (uint) i->oscale_index && (uint) i->class_id == lab)
00412               draw_cross(i->o.h0 * czoom + h0, i->o.w0 * czoom + w, 3,
00413                            color_list[color][0], color_list[color][1],
00414                            color_list[color][2]);
00415             // draw children too
00416             color = 1;
00417             for (bboxes::iterator j = i->children.begin();
00418                  j != i->children.end(); ++j) {
00419               if (k == (uint) j->oscale_index && (uint) j->class_id == lab)
00420                 draw_cross(j->o.h0 * czoom + h0, j->o.w0 * czoom + w, 3,
00421                            color_list[color][0], color_list[color][1],
00422                            color_list[color][2]);
00423             }
00424           }
00425           lab++;
00426           w += (uint) (outx.dim(2) * czoom + 10);
00427         }}
00428       h0 += (uint) (outx.dim(1) * czoom + 20);
00429     }
00430   }
00431 
00432   template <typename T, class Tstate>
00433   void detector_gui<T,Tstate>::
00434   display_preprocessed(svector<midx<T> > &pp, bboxes &bbs,
00435                        vector<string> &labels, uint &h0, uint &w0, double dzoom,
00436                        T vmin, T vmax, uint wmax) {
00437     if (pp.size() != bbs.size())
00438       eblerror("expected same size pp and bbs but got " << pp.size()
00439                << " and " << bbs.size());
00440     idx<T> l;
00441     if (pp.size() > 0) {
00442       midx<T> &m = pp[0];
00443       h0 += 15 * 3;
00444       uint w = w0, h = h0;
00445       gui << white_on_transparent() << at(h0 - 15 * 4, w0) << pp.size()
00446           << " positive windows with dimensions " << m.str();
00447       ostringstream o;
00448       o.precision(3);
00449       uint hmax = 0;
00450       for (uint i = 0; i < pp.size() && w < wmax; ++i) {
00451         h = h0;
00452         m = pp[i];
00453         bbox &b = bbs[i];
00454         // print bbox infos
00455         o.str(""); o << b.confidence; gui << at(h - 15 * 3, w) << o.str();
00456         gui << at(h - 15 * 2, w) << b.oscale_index;
00457         gui << at(h - 15 * 1, w)
00458             << ((uint) b.class_id < labels.size() ?
00459                 labels[b.class_id].c_str() : "***");
00460         // // draw input box
00461         // rect<float> r(h + b.i.h0 - b.i0.h0,
00462         //              w + b.i.w0 - b.i0.w0, b.i.height, b.i.width);
00463         // draw_box(r, 0, 0, 255);
00464 
00465         // loop on each layer of input to get maximum width
00466         int maxw = 0;
00467         for (uint j = 0; j < m.dim(0); ++j) {
00468           l = m.get(j);
00469           maxw = std::max(maxw, (int) l.dim(2));
00470         }
00471         // draw all layers of preprocessed region
00472         for (uint j = 0; j < m.dim(0); ++j) {
00473           l = m.get(j);
00474           int ww = std::max(0, (int) (w + (maxw - l.dim(2)) / 2));
00475           l = l.shift_dim(0, 2);
00476           draw_matrix(l, h, ww, dzoom, dzoom, (T)vmin, (T)vmax);
00477           rect<float> r(h, ww, l.dim(0), l.dim(1));
00478           draw_cross(r.hcenter(), r.wcenter(), 3, 0, 0, 255, 255);
00479           h += l.dim(0) + 1;
00480         }
00481         w += maxw + 2;
00482         hmax = std::max(h, hmax);
00483       }
00484       h0 = hmax + 20;
00485     }
00486   }
00487 
00488   template <typename T, class Tstate> void detector_gui<T,Tstate>::
00489   update_and_display_queue(deque<idx<T> > &queue, uint step, uint qheight,
00490                            uint qwidth, vector<idx<T> > &new_detections,
00491                            uint detcnt, uint &h0, uint &w0, double dzoom) {
00492     // update queue
00493     uint queuesz = qheight * qwidth;
00494     // loop over all new detections and add new ones based on the step
00495     for (typename vector<idx<T> >::iterator i = new_detections.begin();
00496          i != new_detections.end(); ++i, detcnt++) {
00497       if (!(detcnt % std::max((uint) 1, step))) { // add when multiple of step
00498         if ((queue.size() >= queuesz) && (queue.size() > 0))
00499           queue.pop_front();
00500         queue.push_back(*i);
00501       }
00502     }
00503     // display queue
00504     uint w = 0, wn = 0, h = 0;
00505     intg hmax = 0, wmax = 0;
00506     h = h0;
00507     for (typename deque<idx<T> >::iterator i = queue.begin();
00508          i != queue.end(); ++i) {
00509       draw_matrix(*i, h, w0 + w, dzoom, dzoom, (T)0, (T)255);
00510       w += i->dim(1) + 2;
00511       wn++;
00512       hmax = std::max(hmax, i->dim(0));
00513       wmax = std::max(wmax, (intg) w);
00514       if (wn >= qwidth) {
00515         wn = 0;
00516         w = 0;
00517         h += hmax + 2;
00518         hmax = 0;
00519       }
00520     }
00521     // update h0 and w0
00522     h0 += hmax;
00523     w0 += wmax;
00524   }
00525 
00526   template <typename T, class Tstate> template <typename Tin>
00527   bboxes& detector_gui<T,Tstate>::
00528   display_all(detector<T,Tstate> &cl, idx<Tin> &img, double threshold,
00529               const char *frame_name, uint h0, uint w0, double dzoom, T vmin,
00530               T vmax, int wid, const char *wname) {
00531     display_wid_fprop = (wid >= 0) ? wid :
00532       new_window((wname ? wname : "detector: inputs, outputs & internals"));
00533     select_window(display_wid_fprop);
00534 
00535     // draw input and output
00536     bboxes& bb =
00537       display_inputs_outputs(cl, img, threshold, frame_name,
00538                              h0, w0, dzoom, vmin, vmax, display_wid_fprop);
00539 
00540     // disable_window_updates();
00541     // draw internal states of first scale
00542     w0 = (cl.indim.dim(2) + 5) * 2 + 5;
00543     module_1_1_gui mg;
00544     // cl.prepare(img);
00545     // cl.prepare_scale(0);
00546     mg.display_fprop(*(module_1_1<T,Tstate>*) &cl.thenet,
00547                      *cl.input, cl.output, h0, w0, (double) 1.0,
00548                      (T) -1.0, (T) 1.0, true, display_wid_fprop);
00549     //    enable_window_updates();
00550     return bb;
00551   }
00552 
00553   template <typename T, class Tstate> template <typename Tin>
00554   void detector_gui<T,Tstate>::display_current(detector<T,Tstate> &cl,
00555                                                idx<Tin> &sample,
00556                                                int wid, const char *wname,
00557                                                double dzoom){
00558     display_wid_fprop = (wid >= 0) ? wid :
00559       new_window((wname ? wname : "detector: inputs, outputs & internals"));
00560     select_window(display_wid_fprop);
00561     disable_window_updates();
00562     clear_window();
00563     // draw internal states of first scale
00564     module_1_1_gui mg;
00565     cl.prepare(sample);
00566     cl.prepare_scale(0);
00567     mg.display_fprop(*(module_1_1<T,Tstate>*) &cl.thenet,
00568                      *cl.input, cl.output, (uint) 0, (uint) 0, dzoom,
00569                      (T) -1.0, (T) 1.0, true, display_wid_fprop);
00570     enable_window_updates();
00571   }
00572 
00573   template <typename T, class Tstate>
00574   void detector_gui<T,Tstate>::set_mask_class(const char *name, T threshold) {
00575     if (name) {
00576       mask_class = name;
00577       mask_threshold = threshold;
00578     }
00579   }
00580 
00581 } // end namespace ebl
00582 
00583 #endif