contrib/brl/bseg/sdet/sdet_grid_finder.h
Go to the documentation of this file.
00001 // This is brl/bseg/sdet/sdet_grid_finder.h
00002 #ifndef sdet_grid_finder_h_
00003 #define sdet_grid_finder_h_
00004 //---------------------------------------------------------------------
00005 //:
00006 // \file
00007 // \brief a processor for finding a grid of orthogonal lines in an image
00008 //
00009 //  Given a grid with squares of known spacing, the homography that best
00010 //  maps the grid into the image is found by grouping line segments detected
00011 //  in the image to form the vanishing points for the line segments. An
00012 //  approximate homography is established to enable a search for the best
00013 //  fit of the grid in the image. A final homography is computed using all
00014 //  the line-to-line correspondences in a least squares solution
00015 //
00016 // \author
00017 //  J.L. Mundy - April 10, 2003
00018 //
00019 // \verbatim
00020 //  Modifications
00021 //   DEC 9/3/2003 - replaced line_chamfer_1d with grid_profile_matcher
00022 //                - added functions to output homographies to file
00023 //                - added function to check homography with original image
00024 //   Bing Yu 11/22/2007
00025 //                - added an accessor function to output grid points
00026 //                - added an accessor function to set minimum line length
00027 // \endverbatim
00028 //
00029 //-------------------------------------------------------------------------
00030 #include <vcl_vector.h>
00031 #include <vgl/vgl_homg_point_2d.h>
00032 #include <vgl/algo/vgl_h_matrix_2d.h>
00033 #include <vsol/vsol_line_2d_sptr.h>
00034 #include <vsol/vsol_point_2d_sptr.h>
00035 #include <bsol/bsol_hough_line_index_sptr.h>
00036 #include <sdet/sdet_grid_finder_params.h>
00037 #include <vil1/vil1_image.h>
00038 
00039 //this helper class does a distance transform on the perpendicular
00040 //distance of parallel lines from the origin (-l.c());
00041 //offsets into the distance array corresponding to each line
00042 //are provided.
00043 
00044 #if 0
00045 class line_chamfer_1d
00046 {
00047  public:
00048   line_chamfer_1d();
00049   ~line_chamfer_1d();
00050 
00051   bool insert_lines(vcl_vector<vsol_line_2d_sptr> const& lines);
00052 
00053   bool get_lines_in_interval(const double dlo, const double dhi,
00054                              vcl_vector<vsol_line_2d_sptr>& lines) const;
00055   int index_size() const {return size_;}
00056   int n_lines() const {return distances_.size();}
00057   double offset(int i) const {return distances_[i];}
00058   double distance(double x) const;
00059   void forward_champher();
00060   void backward_champher();
00061  private:
00062   vcl_vector<int> index_;
00063   vcl_vector<double> distances_;
00064   vcl_vector<vcl_vector<vsol_line_2d_sptr>* > line_index_;
00065   int size_;
00066   double dmin_;
00067   double dmax_;
00068 };
00069 #endif
00070 
00071 class grid_profile_matcher
00072 {
00073  public:
00074   grid_profile_matcher();
00075   ~grid_profile_matcher();
00076   bool insert_lines(vcl_vector<vsol_line_2d_sptr> const& lines,
00077                     bool horizontal_lines);
00078   bool get_lines_in_interval(const double dlo, const double dhi,
00079                              vcl_vector<vsol_line_2d_sptr>& lines) const;
00080   double calculate_grid_offset(int n_lines, double spacing);
00081   int index_size() const {return size_;}
00082   int n_lines() const {return distances_.size();}
00083   double offset(int i) const {return distances_[i];}
00084   double distance(double x) const;
00085  private:
00086   vnl_vector<double> image_profile_;
00087   vcl_vector<double> distances_;
00088   vcl_vector<vcl_vector<vsol_line_2d_sptr>* > line_index_;
00089   int size_;
00090   double dmin_;
00091   double dmax_;
00092 };
00093 
00094 
00095 class sdet_grid_finder : public sdet_grid_finder_params
00096 {
00097  public:
00098   // Constructors/destructor
00099   sdet_grid_finder(sdet_grid_finder_params& gfp);
00100 
00101   ~sdet_grid_finder();
00102 
00103   // Process methods
00104   bool match_grid();
00105   bool compute_homography();
00106   bool compute_manual_homography(vsol_point_2d_sptr ul,
00107                                  vsol_point_2d_sptr ur,
00108                                  vsol_point_2d_sptr lr,
00109                                  vsol_point_2d_sptr ll);
00110   void clear();
00111 
00112   // Accessors
00113 
00114   //: if there are less than 2 dominant groups then return false
00115   bool set_lines(const float xsize, const float ysize,
00116                  vcl_vector<vsol_line_2d_sptr> const& lines);
00117 
00118   bool get_homography(vgl_h_matrix_2d<double>& homog);
00119 
00120   bool get_debug_lines(vcl_vector<vsol_line_2d_sptr> & lines);
00121   bool get_debug_grid_lines(vcl_vector<vsol_line_2d_sptr> & lines);
00122 
00123   bool get_affine_lines(vcl_vector<vsol_line_2d_sptr> & lines);
00124   bool get_matched_lines(vcl_vector<vsol_line_2d_sptr> & lines);
00125   bool get_mapped_lines(vcl_vector<vsol_line_2d_sptr> & lines);
00126 
00127   bool get_backprojected_grid(vcl_vector<vsol_line_2d_sptr> & lines);
00128   void set_verbose() { verbose_=true; } //non-params interface
00129   void unset_verbose() { verbose_=false; }
00130   void set_line_length_threshold(double length)  { length_threshold_ = length; }
00131 
00132   //: get all grid corner points, in column-major order
00133   bool get_grid_points(vcl_vector<double> &image_x, vcl_vector<double> &image_y);
00134 
00135   //:test camera parameter matrices
00136   bool transform_grid_points(vnl_matrix_fixed<double,3,3> & K,
00137                              vnl_matrix_fixed<double,3,4> & M,
00138                              vcl_vector<vsol_point_2d_sptr> & points);
00139   //:write transformed grid points to a file
00140   bool init_output_file(vcl_ofstream & outstream);
00141   bool write_image_points(vcl_ofstream & outstream);
00142 
00143   //:make sure homography and image correspond with each other
00144   bool check_grid_match(vil1_image img);
00145 
00146  protected:
00147   // protected methods
00148 
00149 
00150   //:transform a vsol line by transforming the end points
00151   vsol_line_2d_sptr transform_line(vgl_h_matrix_2d<double> const& h,
00152                                    vsol_line_2d_sptr const & l);
00153 
00154   //:the vanishing point of a line bundle
00155 
00156   bool get_vanishing_point(vcl_vector<vsol_line_2d_sptr> const & para_lines,
00157                            vgl_homg_point_2d<double>& vp);
00158 
00159   bool scale_transform(const double max_distance,
00160                        vcl_vector<vsol_line_2d_sptr> const& gh,
00161                        vcl_vector<vsol_line_2d_sptr> const& gv,
00162                        vnl_matrix_fixed<double, 3, 3>& S);
00163 
00164 
00165   //:vanishing points of the grid lines
00166   bool compute_vanishing_points();
00167   bool compute_projective_homography();
00168   bool compute_affine_homography();
00169   bool compute_homography_linear_chamfer(vgl_h_matrix_2d<double> & H);
00170 
00171   // for checking homography match with original image
00172   bool get_square_pixel_stats(vil1_image img,
00173                               int x,int y,
00174                               double & mean_intensity,
00175                               double & intensity_sigma);
00176 
00177   //:members
00178   bool groups_valid_;
00179   bool vanishing_points_valid_;
00180   bool projective_homography_valid_;      //process state flag
00181   bool affine_homography_valid_;      //process state flag
00182   bool homography_valid_;      //process state flag
00183   float xmax_;
00184   float ymax_;
00185   vcl_vector<vsol_line_2d_sptr> lines_;
00186   vcl_vector<vsol_line_2d_sptr> display_lines_;
00187   vcl_vector<vsol_line_2d_sptr> matched_lines_;
00188   vcl_vector<vsol_line_2d_sptr> debug_lines_;
00189   vcl_vector<vsol_line_2d_sptr> debug_grid_lines_;
00190   vcl_vector<vsol_line_2d_sptr> group0_;
00191   vcl_vector<vsol_line_2d_sptr> group1_;
00192   vcl_vector<vsol_line_2d_sptr> afgroup0_;
00193   vcl_vector<vsol_line_2d_sptr> afgroup1_;
00194   bsol_hough_line_index_sptr index_;
00195   //line_chamfer_1d chamf0_;
00196   //line_chamfer_1d chamf90_;
00197   grid_profile_matcher chamf0_;
00198   grid_profile_matcher chamf90_;
00199   vgl_homg_point_2d<double> vp0_;
00200   vgl_homg_point_2d<double> vp90_;
00201   vgl_h_matrix_2d<double> projective_homography_;
00202   vgl_h_matrix_2d<double> affine_homography_;
00203   vgl_h_matrix_2d<double> homography_;
00204 
00205   //: grid corner point coordinates in the image
00206   vcl_vector<double> image_x_;
00207   vcl_vector<double> image_y_;
00208 
00209   //: minimum length of line segments used to estimate the vanishing point
00210   //
00211   // Use to ignore short line segments, which are generally less reliable.
00212   double length_threshold_;
00213 };
00214 
00215 #endif // sdet_grid_finder_h_