stereo-vision
All Data Structures Namespaces Functions Modules Pages
elas.h
1 /*
2 Copyright 2011. All rights reserved.
3 Institute of Measurement and Control Systems
4 Karlsruhe Institute of Technology, Germany
5 
6 This file is part of libelas.
7 Authors: Andreas Geiger
8 
9 libelas is free software; you can redistribute it and/or modify it under the
10 terms of the GNU General Public License as published by the Free Software
11 Foundation; either version 3 of the License, or any later version.
12 
13 libelas is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15 PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License along with
18 libelas; if not, write to the Free Software Foundation, Inc., 51 Franklin
19 Street, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21 
22 // Main header file. Include this to use libelas in your code.
23 
24 #ifndef __ELAS_H__
25 #define __ELAS_H__
26 
27 #include <iostream>
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <vector>
32 #include <emmintrin.h>
33 #include <stdint.h>
34 //#define PROFILE 1
35 
36 #ifdef PROFILE
37 #include "timer.h"
38 #endif
39 
40 class Elas {
41 
42 public:
43 
44  enum setting {ROBOTICS,MIDDLEBURY};
45 
46  // parameter settings
47  struct parameters {
48  int32_t disp_min; // min disparity
49  int32_t disp_max; // max disparity
50  float support_threshold; // max. uniqueness ratio (best vs. second best support match)
51  int32_t support_texture; // min texture for support points
52  int32_t candidate_stepsize; // step size of regular grid on which support points are matched
53  int32_t incon_window_size; // window size of inconsistent support point check
54  int32_t incon_threshold; // disparity similarity threshold for support point to be considered consistent
55  int32_t incon_min_support; // minimum number of consistent support points
56  bool add_corners; // add support points at image corners with nearest neighbor disparities
57  int32_t grid_size; // size of neighborhood for additional support point extrapolation
58  float beta; // image likelihood parameter
59  float gamma; // prior constant
60  float sigma; // prior sigma
61  float sradius; // prior sigma radius
62  int32_t match_texture; // min texture for dense matching
63  int32_t lr_threshold; // disparity threshold for left/right consistency check
64  float speckle_sim_threshold; // similarity threshold for speckle segmentation
65  int32_t speckle_size; // maximal size of a speckle (small speckles get removed)
66  int32_t ipol_gap_width; // interpolate small gaps (left<->right, top<->bottom)
67  bool filter_median; // optional median filter (approximated)
68  bool filter_adaptive_mean; // optional adaptive mean filter (approximated)
69  bool postprocess_only_left; // saves time by not postprocessing the right image
70  bool subsampling; // saves time by only computing disparities for each 2nd pixel
71  // note: for this option D1 and D2 must be passed with size
72  // width/2 x height/2 (rounded towards zero)
73 
74  // constructor
75  parameters (setting s=ROBOTICS) {
76 
77  // default settings in a robotics environment
78  // (do not produce results in half-occluded areas
79  // and are a bit more robust towards lighting etc.)
80  if (s==ROBOTICS) {
81  disp_min = 0;
82  disp_max = 255;
83  support_threshold = 0.85;
84  support_texture = 10;
85  candidate_stepsize = 5;
86  incon_window_size = 5;
87  incon_threshold = 5;
88  incon_min_support = 5;
89  add_corners = 0;
90  grid_size = 20;
91  beta = 0.02;
92  gamma = 3;
93  sigma = 1;
94  sradius = 2;
95  match_texture = 1;
96  lr_threshold = 2;
97  speckle_sim_threshold = 1;
98  speckle_size = 200;
99  ipol_gap_width = 3;
100  filter_median = 0;
101  filter_adaptive_mean = 1;
102  postprocess_only_left = 1;
103  subsampling = 0;
104 
105  // default settings for middlebury benchmark
106  // (interpolate all missing disparities)
107  } else {
108  disp_min = 0;
109  disp_max = 255;
110  support_threshold = 0.95;
111  support_texture = 10;
112  candidate_stepsize = 5;
113  incon_window_size = 5;
114  incon_threshold = 5;
115  incon_min_support = 5;
116  add_corners = 1;
117  grid_size = 20;
118  beta = 0.02;
119  gamma = 5;
120  sigma = 1;
121  sradius = 3;
122  match_texture = 0;
123  lr_threshold = 2;
124  speckle_sim_threshold = 1;
125  speckle_size = 200;
126  ipol_gap_width = 5000;
127  filter_median = 1;
128  filter_adaptive_mean = 0;
129  postprocess_only_left = 0;
130  subsampling = 0;
131  }
132  }
133  };
134 
135  // constructor, input: parameters
136  Elas (parameters param) : param(param) {}
137 
138  // deconstructor
139  ~Elas () {}
140 
141  // matching function
142  // inputs: pointers to left (I1) and right (I2) intensity image (uint8, input)
143  // pointers to left (D1) and right (D2) disparity image (float, output)
144  // dims[0] = width of I1 and I2
145  // dims[1] = height of I1 and I2
146  // dims[2] = bytes per line (often equal to width, but allowed to differ)
147  // note: D1 and D2 must be allocated before (bytes per line = width)
148  // if subsampling is not active their size is width x height,
149  // otherwise width/2 x height/2 (rounded towards zero)
150  bool process (uint8_t* I1,uint8_t* I2,float* D1,float* D2,const int32_t* dims);
151 
152 private:
153 
154  struct support_pt {
155  int32_t u;
156  int32_t v;
157  int32_t d;
158  support_pt(int32_t u,int32_t v,int32_t d):u(u),v(v),d(d){}
159  };
160 
161  struct triangle {
162  int32_t c1,c2,c3;
163  float t1a,t1b,t1c;
164  float t2a,t2b,t2c;
165  triangle(int32_t c1,int32_t c2,int32_t c3):c1(c1),c2(c2),c3(c3){}
166  };
167 
168  inline uint32_t getAddressOffsetImage (const int32_t& u,const int32_t& v,const int32_t& width) {
169  return v*width+u;
170  }
171 
172  inline uint32_t getAddressOffsetGrid (const int32_t& x,const int32_t& y,const int32_t& d,const int32_t& width,const int32_t& disp_num) {
173  return (y*width+x)*disp_num+d;
174  }
175 
176  // support point functions
177  void removeInconsistentSupportPoints (int16_t* D_can,int32_t D_can_width,int32_t D_can_height);
178  void removeRedundantSupportPoints (int16_t* D_can,int32_t D_can_width,int32_t D_can_height,
179  int32_t redun_max_dist, int32_t redun_threshold, bool vertical);
180  void addCornerSupportPoints (std::vector<support_pt> &p_support);
181  inline int16_t computeMatchingDisparity (const int32_t &u,const int32_t &v,uint8_t* I1_desc,uint8_t* I2_desc,const bool &right_image);
182  std::vector<support_pt> computeSupportMatches (uint8_t* I1_desc,uint8_t* I2_desc);
183 
184  // triangulation & grid
185  std::vector<triangle> computeDelaunayTriangulation (std::vector<support_pt> p_support,int32_t right_image);
186  void computeDisparityPlanes (std::vector<support_pt> p_support,std::vector<triangle> &tri,int32_t right_image);
187  void createGrid (std::vector<support_pt> p_support,int32_t* disparity_grid,int32_t* grid_dims,bool right_image);
188 
189  // matching
190  inline void updatePosteriorMinimum (__m128i* I2_block_addr,const int32_t &d,const int32_t &w,
191  const __m128i &xmm1,__m128i &xmm2,int32_t &val,int32_t &min_val,int32_t &min_d);
192  inline void updatePosteriorMinimum (__m128i* I2_block_addr,const int32_t &d,
193  const __m128i &xmm1,__m128i &xmm2,int32_t &val,int32_t &min_val,int32_t &min_d);
194  inline void findMatch (int32_t &u,int32_t &v,float &plane_a,float &plane_b,float &plane_c,
195  int32_t* disparity_grid,int32_t *grid_dims,uint8_t* I1_desc,uint8_t* I2_desc,
196  int32_t *P,int32_t &plane_radius,bool &valid,bool &right_image,float* D);
197  void computeDisparity (std::vector<support_pt> p_support,std::vector<triangle> tri,int32_t* disparity_grid,int32_t* grid_dims,
198  uint8_t* I1_desc,uint8_t* I2_desc,bool right_image,float* D);
199 
200  // L/R consistency check
201  void leftRightConsistencyCheck (float* D1,float* D2);
202 
203  // postprocessing
204  void removeSmallSegments (float* D);
205  void gapInterpolation (float* D);
206 
207  // optional postprocessing
208  void adaptiveMean (float* D);
209  void median (float* D);
210 
211 protected:
212  // parameter set
213  parameters param;
214 
215 private:
216  // memory aligned input images + dimensions
217  uint8_t *I1,*I2;
218  int32_t width,height,bpl;
219 
220  // profiling timer
221 #ifdef PROFILE
222  Timer timer;
223 #endif
224 };
225 
226 #endif