contrib/brl/bbas/bgui/bgui_bmrf_soview2D.cxx
Go to the documentation of this file.
00001 #include "bgui_bmrf_soview2D.h"
00002 //:
00003 // \file
00004 #include <bseg/bmrf/bmrf_epi_seg.h>
00005 #include <bseg/bmrf/bmrf_epi_point_sptr.h>
00006 #include <bseg/bmrf/bmrf_epi_point.h>
00007 
00008 #include <vcl_iostream.h>
00009 #include <vcl_limits.h>
00010 #include <vcl_vector.h>
00011 #include <vcl_algorithm.h>
00012 
00013 #include <vgl/vgl_distance.h>
00014 #include <vgui/vgui_gl.h>
00015 #include <vgui/vgui_soview2D.h>
00016 #include <vil/vil_image_view.h>
00017 
00018 
00019 // Constructor
00020 bgui_bmrf_epi_seg_soview2D::bgui_bmrf_epi_seg_soview2D( bmrf_epi_seg_sptr const & seg,
00021                                                         const bmrf_epipole& epipole,
00022                                                         bool intensity )
00023  : seg_sptr_(seg), intensity_view_ (NULL)
00024 {
00025   if (intensity)
00026     intensity_view_ = make_intensity_view(epipole);
00027 }
00028 
00029 
00030 //: Destructor
00031 bgui_bmrf_epi_seg_soview2D::~bgui_bmrf_epi_seg_soview2D()
00032 {
00033   delete intensity_view_;
00034 }
00035 
00036 
00037 //: Render the bmrf_epi_seg on the display.
00038 void
00039 bgui_bmrf_epi_seg_soview2D::draw() const
00040 {
00041   if (intensity_view_)
00042     intensity_view_->draw();
00043 
00044   glBegin(GL_LINE_STRIP);
00045   vcl_vector<bmrf_epi_point_sptr>::const_iterator p_itr;
00046   for (p_itr = seg_sptr_->begin(); p_itr != seg_sptr_->end(); ++p_itr)
00047     glVertex2f((*p_itr)->x(), (*p_itr)->y());
00048   glEnd();
00049 }
00050 
00051 
00052 //: Print details about this bmrf_epi_seg to the given stream.
00053 vcl_ostream&
00054 bgui_bmrf_epi_seg_soview2D::print(vcl_ostream&s) const
00055 {
00056   return s << "[ a bmrf_epi_seg FIXME ]";
00057 }
00058 
00059 
00060 //: Returns the distance squared from this bmrf_epi_seg to the given position.
00061 float
00062 bgui_bmrf_epi_seg_soview2D::distance_squared(float x, float y) const
00063 {
00064   if (seg_sptr_->n_pts() == 0)
00065     return vcl_numeric_limits<float>::infinity();
00066   if (seg_sptr_->n_pts() == 1) {
00067     bmrf_epi_point_sptr pt = *(seg_sptr_->begin());
00068     float dx = x-pt->x();
00069     float dy = y-pt->y();
00070     return dx*dx + dy*dy;
00071   }
00072 
00073   float dd = -1.0f;
00074   vcl_vector<bmrf_epi_point_sptr>::const_iterator p_itr;
00075   for (p_itr = seg_sptr_->begin(); (p_itr+1) != seg_sptr_->end(); ++p_itr) {
00076     float nd = vgl_distance2_to_linesegment(float((*p_itr)->x()),     float((*p_itr)->y()),
00077                                             float((*(p_itr+1))->x()), float((*(p_itr+1))->y()),
00078                                             x, y);
00079     if (dd<0 || nd<dd)
00080       dd = nd;
00081   }
00082   return dd;
00083 }
00084 
00085 
00086 //: Returns the centroid of this bmrf_epi_seg.
00087 void
00088 bgui_bmrf_epi_seg_soview2D::get_centroid(float* x, float* y) const
00089 {
00090   *x = 0;
00091   *y = 0;
00092   int n=0;
00093   vcl_vector<bmrf_epi_point_sptr>::const_iterator p_itr;
00094   for (p_itr = seg_sptr_->begin(); p_itr != seg_sptr_->end(); ++p_itr, ++n) {
00095     *x += (*p_itr)->x();
00096     *y += (*p_itr)->y();
00097   }
00098   float s = 1.0f / float(n);
00099   *x *= s;
00100   *y *= s;
00101 }
00102 
00103 
00104 //: Translate this soview2D by the given x and y distances.
00105 void
00106 bgui_bmrf_epi_seg_soview2D::translate(float x, float y)
00107 {
00108   // WARNING - This updates x,y position of each point but DOES NOT
00109   //           adjust any other dependent variables such as s and alpha
00110   vcl_vector<bmrf_epi_point_sptr>::const_iterator p_itr;
00111   for (p_itr = seg_sptr_->begin(); p_itr != seg_sptr_->end(); ++p_itr) {
00112     (*p_itr)->set( (*p_itr)->x()+x, (*p_itr)->y()+y );
00113   }
00114 }
00115 
00116 
00117 vgui_soview2D_image*
00118 bgui_bmrf_epi_seg_soview2D::make_intensity_view(const bmrf_epipole& epipole) const
00119 {
00120   double min_a = seg_sptr_->min_alpha(), max_a = seg_sptr_->max_alpha();
00121   double da = (max_a - min_a)/seg_sptr_->n_pts();
00122   int min_u = vcl_numeric_limits<int>::max();
00123   int max_u = vcl_numeric_limits<int>::min();
00124   int min_v = min_u, max_v = max_u;
00125   for (double a = min_a; a<=max_a; a+=da)
00126   {
00127     double ld = seg_sptr_->left_ds(a);
00128     double rd = seg_sptr_->right_ds(a);
00129     double s = seg_sptr_->s(a);
00130     double u,v;
00131     epipole.to_img_coords(s-ld, a, u, v);
00132     int ui = (int)(u+0.5), vi = (int)(v+0.5);
00133     min_u = vcl_min(min_u, ui);  max_u = vcl_max(max_u, ui);
00134     min_v = vcl_min(min_v, vi);  max_v = vcl_max(max_v, vi);
00135 
00136     epipole.to_img_coords(s+rd, a, u, v);
00137     ui = (int)(u+0.5); vi = (int)(v+0.5);
00138     min_u = vcl_min(min_u, ui);  max_u = vcl_max(max_u, ui);
00139     min_v = vcl_min(min_v, vi);  max_v = vcl_max(max_v, vi);
00140   }
00141 
00142   vil_image_view< vxl_byte> img( max_u - min_u +1,
00143                                  max_v - min_v +1,
00144                                  4 );
00145   img.fill(0);
00146   for (double a = min_a; a<=max_a; a+=da)
00147   {
00148     double ld = seg_sptr_->left_ds(a);
00149     vxl_byte li = vxl_byte(seg_sptr_->left_int(a)*255.0);
00150     double rd = seg_sptr_->right_ds(a);
00151     vxl_byte ri = vxl_byte(seg_sptr_->right_int(a)*255.0);
00152     double s = seg_sptr_->s(a);
00153 
00154     for (int i=0; i<=(int)ld; ++i) {
00155       double u,v;
00156       epipole.to_img_coords(s-i, a, u, v);
00157       int ui = (int)(u+0.5)-min_u, vi = (int)(v+0.5)-min_v;
00158       img(ui,vi,0) = li;
00159       img(ui,vi,1) = li;
00160       img(ui,vi,2) = li;
00161       img(ui,vi,3) = 255;
00162     }
00163     for (int i=0; i<=(int)rd; ++i) {
00164       double u,v;
00165       epipole.to_img_coords(s+i, a, u, v);
00166       int ui = (int)(u+0.5)-min_u, vi = (int)(v+0.5)-min_v;
00167       img(ui,vi,0) = ri;
00168       img(ui,vi,1) = ri;
00169       img(ui,vi,2) = ri;
00170       img(ui,vi,3) = 255;
00171     }
00172   }
00173   return new vgui_soview2D_image((float)min_u, (float)min_v, img, true);
00174 }