KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
edge_chamfer_likelihood.h
Go to the documentation of this file.
1 /* $Id: edge_chamfer_likelihood.h 17393 2014-08-23 20:19:14Z predoehl $ */
2 /* =========================================================================== *
3  |
4  | Copyright (c) 1994-2010 by Kobus Barnard (author)
5  |
6  | Personal and educational use of this code is granted, provided that this
7  | header is kept intact, and that the authorship is not misrepresented, that
8  | its use is acknowledged in publications, and relevant papers are cited.
9  |
10  | For other use contact the author (kobus AT cs DOT arizona DOT edu).
11  |
12  | Please note that the code in this file has not necessarily been adequately
13  | tested. Naturally, there is no guarantee of performance, support, or fitness
14  | for any particular task. Nonetheless, I am interested in hearing about
15  | problems that you encounter.
16  |
17  | Author: Kyle Simek
18  * =========================================================================== */
19 
20 #ifndef KJB_EDGE_CHAMFER_LIKELIHOOD_H
21 #define KJB_EDGE_CHAMFER_LIKELIHOOD_H
22 
23 #include <l/l_incl.h>
24 #include <l/l_def.h>
25 #include <edge_cpp/edge.h>
26 #include <edge/edge_base.h>
27 #include <g/g_chamfer.h>
28 #include <l/l_int_matrix.h>
29 #include <m/m_matrix.h>
30 #include <m_cpp/m_int_matrix.h>
31 #include <i_cpp/i_image.h>
32 #include <vector>
33 #include <list>
34 
35 #include <l_cpp/l_debug.h>
36 
37 #include "edge_cpp/edge_chamfer.h"
38 
39 #ifdef KJB_HAVE_GLEW
40 #include "GL/glew.h"
41 #endif
42 
43 #include <gr_cpp/gr_opengl.h>
45 #include <gr_cpp/gr_sprite.h>
46 #include <gr_cpp/gr_renderable.h>
48 
49 #ifdef KJB_HAVE_CUDA
50 #include <cuda.h>
51 #include <cudaGL.h>
52 #endif
53 
54 #ifdef KJB_HAVE_CUDPP
55 #include <cudpp.h>
56 #endif
57 
58 #include <gpu_cpp/gpu_cudpp.h>
59 
60 
61 #include <gpu_cpp/gpu_cuda.h>
62 #include <gpu_cpp/gpu_cuda_util.h>
63 
64 #ifdef TEST
65 #include <gr_cpp/gr_display.h>
66 #endif
67 
68 namespace kjb {
69 
70 
71 
72 #ifdef KJB_HAVE_OPENGL
73 #ifdef KJB_HAVE_GLEW
74 class Base_chamfer_likelihood
75 {
76 public:
77  Base_chamfer_likelihood(size_t width, size_t height) :
78  sum_(0),
79  model_points_(0),
80  data_points_(0),
81  correspondences_(0),
82  square_values_(false),
83  offscreen_buffer_(width, height)
84  {
85  }
86 
88  size_t get_num_model_points() const
89  {
90  return model_points_;
91  }
92 
94  size_t get_num_correspondences() const
95  {
96  return correspondences_;
97  }
98 
100  size_t get_num_data_points() const
101  {
102  return data_points_;
103  }
104 
110  double get_sum() const
111  {
112  if(square_values_)
113  {
114  KJB_THROW_2(Runtime_error, "Attempting to get sum when square_values is set. Use get_sq_sum() instead.");
115  }
116  return sum_;
117  }
118 
124  double get_sq_sum() const
125  {
126  if(!square_values_)
127  {
128  KJB_THROW_2(Runtime_error, "Attempting to get squared sum when square_values is not set. Use get_sum() instead, or call square_values(true) and re-evaluate.");
129  }
130  return sum_;
131  }
132 
136  void square_values(bool enabled)
137  {
138  square_values_ = enabled;
139  }
140 
141 protected:
142  double sum_;
143  size_t model_points_;
144  size_t data_points_;
145  size_t correspondences_;
146 
147  bool square_values_;
148 
149  ::kjb::opengl::Fbo_offscreen_buffer offscreen_buffer_;
150 };
151 
152 
153 #ifdef KJB_HAVE_CUDA
154 
155 class Base_gpu_chamfer_likelihood : public Base_chamfer_likelihood
156 {
157 typedef Base_chamfer_likelihood Base;
158 public:
163  Base_gpu_chamfer_likelihood(int width_in, int height_in) :
164  Base(width_in, height_in),
165  cuda_rbo_handle_(),
166  reduce_mod_()
167  {
168  CU_ETX(cuGraphicsGLRegisterImage(
169  &cuda_rbo_handle_,
170  offscreen_buffer_.get_color_buffer(),
171  GL_RENDERBUFFER,
172  CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE));
173  }
174 
175 
177  virtual void operator()(const Renderable& object) = 0;
178 
179  virtual ~Base_gpu_chamfer_likelihood()
180  {
181  cuGraphicsUnregisterResource(cuda_rbo_handle_);
182  }
183 
184 protected:
185 
186  CUarray map_rbo();
187 
188  void render_to_fbo(const Renderable& object);
189 
190  void unmap_rbo()
191  {
192  CU_ETX(cuGraphicsUnmapResources(1, &cuda_rbo_handle_, 0));
193  }
194 protected:
195  CUgraphicsResource cuda_rbo_handle_;
196 
197  gpu::Cuda_reduce_module reduce_mod_;
198 };
199 
200 
201 #ifdef KJB_HAVE_CUDPP
202 class Gpu_chamfer_likelihood : public Base_gpu_chamfer_likelihood
203 {
204 public:
208  Gpu_chamfer_likelihood(int width, int height);
209 
210 
211 
212  virtual ~Gpu_chamfer_likelihood()
213  {
214  cudppDestroy(cudpp_handle_);
215  cuMemFree(buffer_ptr_);
216  cuMemFree(workspace_ui_);
217  }
218 
228  void set_maps(const CUdeviceptr distance, const CUdeviceptr position, size_t num_edges, size_t N = 0);
229 
234  CUdeviceptr create_distance_map(const Matrix& distance_map);
235 
242  CUdeviceptr create_position_map(const std::vector<Int_matrix>& position_map)
243  {
244  return create_position_map(position_map[0], position_map[1]);
245  }
246 
253  CUdeviceptr create_position_map(const Int_matrix& row_position_map, const Int_matrix& col_position_map);
254 
262  void operator()(const Renderable& r);
263 
264 
265 
266 
267 
269  void gold_standard_process(const Renderable& r, const Chamfer_transform& xfm)
270  {
271  std::vector<Int_matrix> positions = xfm.position_map();
272 
273  gold_standard_process(r, xfm.distance_map(), positions[0], positions[1], xfm.get_num_points());
274  }
275 
277  void gold_standard_process(const Renderable& r, Matrix distance, const Int_matrix& row_position, const Int_matrix& col_position, size_t num_points) ;
278 
279 #ifdef TEST
280  Matrix get_buffer() const;
282 
283  // display the current contents of this object's frame-buffer object.
284  void display_buffer(const std::string& str = "") const;
285 #endif /* TEST */
286 
287 private:
289  CUdeviceptr array_to_linear(CUarray array);
290 
291 
299  void uint_cuda_sort_(CUdeviceptr uint_array);
300 
312  double uint_reduce_(CUdeviceptr uint_array, CUdeviceptr workspace);
313 
314 
315  gpu::Cuda_utility_module util_mod_;
316 
317  CUDPPHandle cudpp_handle_;
318 
319  CUdeviceptr distance_map_;
320  CUdeviceptr position_map_;
321  CUdeviceptr buffer_ptr_;
322  CUdeviceptr workspace_ui_;
323 
324 #if CUDA_VERSION < 3020
325  unsigned int buffer_pitch_bytes_;
326 #else
327  size_t buffer_pitch_bytes_;
328 #endif
329 
330  size_t buffer_pitch_elements_;
331  size_t N_;
332 
333 };
334 
335 
336 
340 class Multi_gpu_chamfer_likelihood
341 {
342 public:
348  Multi_gpu_chamfer_likelihood(int width, int height, int modulo = 1) :
349  distance_maps_(),
350  position_maps_(),
351  data_point_sizes_(),
352  likelihood_(width, height),
353  sum_(0),
354  model_points_(0),
355  data_points_(0),
356  correspondences_(0),
357  square_values_(false),
358  modulo_(modulo),
359  view_list_()
360  { }
361 
362  Multi_gpu_chamfer_likelihood(int width, int height, const std::vector<size_t>& view_list) :
363  distance_maps_(),
364  position_maps_(),
365  data_point_sizes_(),
366  likelihood_(width, height),
367  sum_(0),
368  model_points_(0),
369  data_points_(0),
370  correspondences_(0),
371  square_values_(false),
372  modulo_(1),
373  view_list_(view_list)
374  { }
375 
376 
377  void square_values(bool enabled)
378  {
379  // storing the state here and in the inner
380  // likelihood is not very elegant...
381 
382  square_values_ = enabled;
383  likelihood_.square_values(enabled);
384  }
385 
389  virtual void push_back(const Chamfer_transform& xfm);
390 
391 
400  virtual void push_back(
401  const Matrix& distance_map,
402  const Int_matrix& row_position_map,
403  const Int_matrix& col_position_map,
404  size_t num_points);
405 
406 
407  virtual void operator()(const Mv_renderable& m);
408 
409  std::vector<size_t> get_view_list(const size_t num_views);
410 
418  void gold_standard_evaluate(
419  const Mv_renderable& m,
420  std::vector<Matrix> distances,
421  std::vector<Int_matrix> row_positions,
422  std::vector<Int_matrix> col_positions,
423  std::vector<size_t> num_points
424  );
425 
426 
427 
428  double get_sum() const
429  {
430  if(square_values_)
431  {
432  KJB_THROW_2(Runtime_error, "Attempting to get sum when square_values is set. Use get_sq_sum() instead.");
433  }
434  return sum_;
435  }
436 
437  double get_sq_sum() const
438  {
439  if(!square_values_)
440  {
441  KJB_THROW_2(Runtime_error, "Attempting to get squared sum when square_values is not set. Use get_sum() instead, or call square_values(true) and re-evaluate.");
442  }
443 
444  return sum_;
445  }
446 
447  size_t get_num_correspondences() const
448  {
449  return correspondences_;
450  }
451 
452  size_t get_num_data_points() const
453  {
454  return data_points_;
455  }
456 
457  size_t get_num_model_points() const
458  {
459  return model_points_;
460  }
461 
462 #ifdef TEST
463  void display_buffer(const std::string title = "") const
464  {
465  likelihood_.display_buffer(title);
466  }
467 
468  Matrix get_buffer() const
469  {
470  return likelihood_.get_buffer();
471  }
472 #endif /* TEST */
473 
474  ~Multi_gpu_chamfer_likelihood();
475 
476 
477 private:
478  std::vector<CUdeviceptr> distance_maps_;
479  std::vector<CUdeviceptr> position_maps_;
480  std::vector<size_t> data_point_sizes_;
481  Gpu_chamfer_likelihood likelihood_;
482 
483  double sum_;
484  size_t model_points_;
485  size_t data_points_;
486  size_t correspondences_;
487 
488  bool square_values_;
489 
490  size_t modulo_;
491  std::vector<size_t> view_list_;
492 };
493 
494 
495 
496 
497 #endif /* have cudpp */
498 
499 #endif /* have cuda */
500 
501 class Chamfer_likelihood : public Base_chamfer_likelihood
502 {
503 public:
504  Chamfer_likelihood(size_t width, size_t height) :
505  Base_chamfer_likelihood(width, height),
506  distance_(NULL),
507  row_position_(),
508  col_position_(),
509  num_edges_()
510  {}
511 
512  void set_maps(
513  const Matrix& distance,
514  const Int_matrix& row_position,
515  const Int_matrix& col_position,
516  size_t num_edges);
517 
519  void set_maps(const Chamfer_transform& xfm)
520  {
521  xfm.position_map(row_position_, col_position_);
522 
523  set_maps(xfm.distance_map(), row_position_, col_position_, xfm.get_num_points());
524  }
525 
534  void operator()(const Renderable& r, bool invert_y = true);
535  void operator()(const kjb::Matrix& img);
536 
537  void evaluate_dispatch_(float* buffer, bool invert_y);
538 private:
539  const Matrix* distance_;
540  Int_matrix row_position_;
541  Int_matrix col_position_;
542  size_t num_edges_;
543 };
544 #endif /* have glew */
545 #endif /* have opengl */
546 
547 } // namespace kjb
548 
549 #endif
height
Definition: APPgetLargeConnectedEdges.m:33
r
Definition: APPgetLargeConnectedEdges.m:127
Abstract class to render this object with GL.
#define KJB_THROW_2(ex, msg)
Definition: l_exception.h:48
This class implements matrices, in the linear-algebra sense, with real-valued elements.
Definition: m_matrix.h:94
Code for a wrapper class around the C struct KJB_Image.
for m
Definition: APPgetLargeConnectedEdges.m:64