contrib/brl/bbas/bsta/vis/bsta_svg_tools.h
Go to the documentation of this file.
00001 // This is brl/bbas/bsta/vis/bsta_svg_tools.h
00002 #ifndef bsta_svg_tools_h_
00003 #define bsta_svg_tools_h_
00004 //:
00005 // \file
00006 // \brief Visualization of bsta_histograms using bsvg
00007 // \author Ozge C. Ozcanli
00008 // \date April 22, 2009
00009 
00010 #include <vcl_iostream.h>
00011 #include <vcl_sstream.h>
00012 #include <bsta/bsta_histogram.h>
00013 #include <bsta/bsta_joint_histogram.h>
00014 #include <bxml/bsvg/bsvg_plot.h>
00015 #include <bxml/bxml_write.h>
00016 #include <vnl/vnl_math.h>
00017 
00018 //: Create SVG document from histogram
00019 // \relatesalso bsta_histogram
00020 template <class T>
00021 void write_svg(const bsta_histogram<T>& h, const vcl_string& outfile,
00022                float width = 600.0f, float height = 600.0f, float margin = 40.0f, int font_size = 30)
00023 {
00024   bsvg_plot pl(width, height);
00025   if (false) pl.set_margin(margin); // TODO
00026   if (false) pl.set_font_size(font_size); // TODO
00027   T min = h.min();
00028   T max = h.max();
00029   T delta = h.delta();
00030   vcl_cout << "min: " << min << " max: " << max << vcl_endl;
00031   T abs_min = T(10);
00032   T abs_max = T(0);
00033   for (unsigned a = 0; a < h.nbins(); a++) {
00034     if (h.p(a) < min) abs_min = h.p(a);
00035     if (h.p(a) > max) abs_max = h.p(a);
00036   }
00037   vcl_stringstream mss; mss << "abs min: " << abs_min << " max: " << abs_max;
00038   vcl_stringstream mss2; mss2 << "ent: " << h.entropy();
00039   bsvg_text* tmm = new bsvg_text(mss.str());
00040   tmm->set_location(margin, margin);
00041   pl.add_element(tmm);
00042   bsvg_text* tmm2 = new bsvg_text(mss2.str());
00043   tmm2->set_location(margin, margin+font_size);
00044   pl.add_element(tmm2);
00045 
00046   float minf = float(min);
00047   float deltaf = float(delta);
00048 
00049   pl.add_axes(0, 1, 0, 1);
00050   pl.add_y_increments(0.1f);
00051 
00052   vcl_vector<float> ps;
00053   vcl_vector<float> x_labels;
00054   for (unsigned i = 0; i < h.nbins(); ++i, minf+=deltaf) {
00055     ps.push_back(float(h.p(i)));
00056     x_labels.push_back(minf);
00057   }
00058 
00059   pl.add_bars(ps, x_labels, true, "red");
00060 
00061   bxml_write(outfile, pl);
00062 }
00063 
00064 //: Create a polar style pie chart from the joint histogram, assuming that the first dimension is the angle, and it is in radius
00065 template <class T>
00066 void write_svg_angle_distance(const bsta_joint_histogram<T>& h, const vcl_string& out_file,
00067                               float width = 600.0f, float height = 600.0f, float margin = 40.0f, int font_size = 30)
00068 {
00069   bsvg_plot pl(width, height);
00070   T mina = h.min_a();
00071   T maxa = h.max_a();
00072   T minb = h.min_b();
00073   T maxb = h.max_b();
00074   T delta_a = h.delta_a();
00075   T delta_b = h.delta_b();
00076   vcl_cout << "min_a: " << mina << " max_a: " << maxa << " min_b: " << minb << " max_b: " << maxb << vcl_endl;
00077   T min = T(10);
00078   T max = T(0);
00079   for (unsigned a = 0; a < h.nbins_a(); a++)
00080     for (unsigned b= 0; b < h.nbins_b(); b++) {
00081       if (h.p(a,b) < min) min = h.p(a,b);
00082       if (h.p(a,b) > max) max = h.p(a,b);
00083     }
00084   vcl_stringstream mss; mss << "abs min: " << min << " max: " << max;
00085   vcl_stringstream mss2; mss2 << "ent: " << h.entropy();
00086   bsvg_text* tmm = new bsvg_text(mss.str());
00087   tmm->set_location(margin, margin);
00088   pl.add_element(tmm);
00089   bsvg_text* tmm2 = new bsvg_text(mss2.str());
00090   tmm2->set_location(margin, margin+font_size);
00091   pl.add_element(tmm2);
00092 
00093 
00094   // scale the distances to the scale of the plot
00095   float factor = (height - 2*margin) / (2*maxb);
00096 
00097   // now add the splices starting from the outer most bins
00098   for (float valb = maxb; valb >= minb; valb -= delta_b) {
00099     float radius = valb*factor; vcl_stringstream rs; rs << (int)(valb);
00100     bsvg_text* t = new bsvg_text(rs.str());
00101     t->set_location(300.0f, 315.0f+radius);
00102     pl.add_element(t);
00103     for (float vala = (float)mina; vala < maxa; vala += delta_a) {
00104       float mag = (h.p(vala+0.005f, valb)/max)*255;
00105 #ifdef DEBUG
00106       vcl_cout << ' ' << mag << ' ';
00107 #endif
00108       unsigned channel = (unsigned)mag;
00109       pl.add_splice(300.0f, 300.0f, radius, vala, vala+delta_a, 255, 255-channel, 255-channel);
00110     }
00111 #ifdef DEBUG
00112     vcl_cout << '\n';
00113 #endif
00114   }
00115 
00116   for (float vala = (float)mina; vala < maxa; vala += delta_a) {
00117     vcl_stringstream rs; rs << (int)(vala*vnl_math::deg_per_rad);
00118     bsvg_text* t = new bsvg_text(rs.str());
00119     float radius = maxb*factor+font_size;
00120     t->set_location((float)(300.0f+(radius)*vcl_cos(vala+vnl_math::pi*0.01)), (float)(300.0f+(radius)*-vcl_sin(vala+vnl_math::pi*0.01)));
00121     pl.add_element(t);
00122   }
00123 
00124   if (minb > 0) {
00125     pl.add_splice(300.0f, 300.0f, factor*minb, 0, float(vnl_math::pi), "gray");
00126     pl.add_splice(300.0f, 300.0f, factor*minb, -float(vnl_math::pi), 0, "gray");
00127   }
00128 
00129   bxml_write(out_file, pl);
00130 }
00131 
00132 #endif // bsta_svg_tools_h_