PICCANTE  0.4
The hottest HDR imaging library!
harris_corner_detector.hpp
Go to the documentation of this file.
1 /*
2 
3 PICCANTE
4 The hottest HDR imaging library!
5 http://vcg.isti.cnr.it/piccante
6 
7 Copyright (C) 2014
8 Visual Computing Laboratory - ISTI CNR
9 http://vcg.isti.cnr.it
10 First author: Francesco Banterle
11 
12 This Source Code Form is subject to the terms of the Mozilla Public
13 License, v. 2.0. If a copy of the MPL was not distributed with this
14 file, You can obtain one at http://mozilla.org/MPL/2.0/.
15 
16 */
17 
18 #ifndef PIC_FEATURES_MATCHING_HARRIS_CORNER_DETECTOR_HPP
19 #define PIC_FEATURES_MATCHING_HARRIS_CORNER_DETECTOR_HPP
20 
21 #include <vector>
22 
23 #include "../util/vec.hpp"
24 #include "../util/std_util.hpp"
25 #include "../util/polynomial.hpp"
26 #include "../base.hpp"
27 
28 #include "../image.hpp"
29 #include "../filtering/filter_luminance.hpp"
30 #include "../filtering/filter_gaussian_2d.hpp"
31 #include "../filtering/filter_gradient_harris_opt.hpp"
32 #include "../filtering/filter_max.hpp"
33 #include "../features_matching/general_corner_detector.hpp"
34 
35 #ifndef PIC_DISABLE_EIGEN
36 
37 #ifndef PIC_EIGEN_NOT_BUNDLED
38  #include "../externals/Eigen/Dense"
39 #else
40  #include <Eigen/Dense>
41 #endif
42 
43 #endif
44 
45 namespace pic {
46 
48 
49 #ifndef PIC_DISABLE_EIGEN
50 
55 {
56 protected:
60 
61  //Harris Corners detector parameters
62  float sigma, threshold, ki;
63  int radius;
65 
66  //previous values
67  int width, height;
68 
72  void release()
73  {
74  lum = delete_s(lum);
77  ret = delete_s(ret);
78  }
79 
83  void setNULL()
84  {
85  type = CD_NOBLE;
86  width = -1;
87  height = -1;
88  lum = NULL;
89  I_grad = NULL;
90  I_grad_flt = NULL;
91  ret = NULL;
92  }
93 
94 public:
95 
102  HarrisCornerDetector(float sigma = 1.0f, int radius = 3,
103  float threshold = 0.001f, float ki = 0.04f,
105  {
106  setNULL();
108  }
109 
111  {
112  release();
113  }
114 
121  void update(float sigma = 1.0f, int radius = 3,
122  float threshold = 0.001f, float ki = 0.04f,
124  {
125  this->sigma = sigma > 0.0f ? sigma : 1.0f;
126  this->radius = radius > 0 ? radius : 1;
127  this->threshold = threshold;
128  this->type = type;
129  this->ki = CLAMPi(ki, 0.04f, 0.06f);
130  }
131 
137  void execute(Image *img, std::vector< Eigen::Vector2f > *corners)
138  {
139  if(img == NULL || corners == NULL) {
140  return;
141  }
142 
143  if((img->width != width) || (img->height != height)) {
144  width = img->width;
145  height = img->height;
146 
147  release();
148  }
149 
150  if(img->channels == 1) {
151  lum = img->clone();
152  } else {
154  }
155 
156  float minL, maxL;
157  lum->getMinVal(NULL, &minL);
158  lum->getMaxVal(NULL, &maxL);
159 
160  float delta = maxL - minL;
161 
162  *lum -= minL;
163  *lum *= delta;
164 
165  corners->clear();
166 
167  std::vector< Eigen::Vector3f > corners_w_quality;
168 
169  //compute gradients
171 
172  float eps = 2.2204e-16f;
173 
174  //filter gradient values
175  FilterGaussian2D flt(sigma);
177 
178  if(ret == NULL) {
180  }
181 
182  //ret = (Ix2.*Iy2 - Ixy.^2)./(Ix2 + Iy2 + eps);
183  for(int i = 0; i < height; i++) {
184  for(int j = 0; j < width; j++) {
185  float *data_ret = (*ret)(j, i);
186 
187  float *I_grad_val = (*I_grad_flt)(j, i);
188 
189  float x2 = I_grad_val[0];
190  float y2 = I_grad_val[1];
191  float xy = I_grad_val[2];
192 
193  float detA = x2 * y2 - xy * xy;
194  float trA = x2 + y2;
195 
196  switch(type)
197  {
198  case CD_SHI_TOMASI: {
199 
200  float x0, x1;
201  if(Polynomial::getSecondOrderRoots(1.0f, -trA, detA, &x0, &x1)) {
202  data_ret[0] = x0 < x1 ? x0 : x1;
203  } else {
204  data_ret[0] = -1.0f;
205  }
206  } break;
207 
208  case CD_HARRIS: {
209  data_ret[0] = detA - ki * trA * trA;
210  } break;
211 
212  case CD_NOBLE: {
213  data_ret[0] = detA / (trA + eps);
214  } break;
215  }
216 
217  }
218  }
219 
220  //non-maximal supression
221  lum = FilterMax::execute(ret, lum, (radius << 1) + 1);
222  Image* ret_flt = lum;
223 
224  float w = 1.0f;
225 
226  int bestPoints = -1;
227 
228  if(threshold < 0.0f) { //the best i-th points
229  bestPoints = int(-threshold);
230  threshold = -FLT_MAX;
231  }
232 
233  for(int i = 0; i < height; i++) {
234  float i_f = float(i);
235  float cx, cy, ax, ay, bx, by, x, y;
236 
237  for(int j = 0; j < width; j++) {
238 
239  float R = (*ret)(j, i)[0];
240  float R_flt = (*ret_flt)(j, i)[0];
241 
242  if((R == R_flt) && (R > threshold)) {
243  float Rr = (*ret)(j, i + 1)[0];
244  float Rl = (*ret)(j, i - 1)[0];
245  float Ru = (*ret)(j + 1, i)[0];
246  float Rd = (*ret)(j - 1, i)[0];
247 
248  cx = R;
249  ax = (Rl + Rr) / 2.0f - cx;
250  bx = ax + cx - Rl;
251 
252  if(ax != 0.0f) {
253  x = -w * bx / (2.0f * ax);
254  } else {
255  x = 0.0f;
256  }
257 
258  cy = R;
259  ay = (Rd + Ru) / 2.0f - cy;
260  by = ay + cy - Rd;
261 
262  if(ay != 0.0f) {
263  y = -w * by / (2.0f * ay);
264  } else {
265  y = 0.0f;
266  }
267 
268  corners_w_quality.push_back(Eigen::Vector3f(float(j) + x, i_f + y, R));
269  }
270  }
271  }
272 
273  sortCornersAndTransfer(&corners_w_quality, corners, bestPoints);
274  }
275 };
276 
277 #endif
278 
279 } // end namespace pic
280 
281 #endif /* PIC_FEATURES_MATCHING_HARRIS_CORNER_DETECTOR_HPP */
282 
Definition: filter_luminance.hpp:28
void release()
release
Definition: harris_corner_detector.hpp:72
void update(float sigma=1.0f, int radius=3, float threshold=0.001f, float ki=0.04f, CORENE_DETECTOR_TYPE type=CD_NOBLE)
update
Definition: harris_corner_detector.hpp:121
int channels
Definition: image.hpp:80
T * delete_s(T *data)
delete_s
Definition: std_util.hpp:123
~HarrisCornerDetector()
Definition: harris_corner_detector.hpp:110
void execute(Image *img, std::vector< Eigen::Vector2f > *corners)
execute
Definition: harris_corner_detector.hpp:137
static Image * execute(Image *imgIn, Image *imgOut=NULL, int colorChannel=0)
execute
Definition: filter_gradient_harris_opt.hpp:78
float sigma
Definition: harris_corner_detector.hpp:62
CORENE_DETECTOR_TYPE type
Definition: harris_corner_detector.hpp:64
static bool getSecondOrderRoots(float a, float b, float c, float *x0, float *x1)
getSecondOrderRoots solves second order equations, ax^2 + b x + c = 0
Definition: polynomial.hpp:437
HarrisCornerDetector(float sigma=1.0f, int radius=3, float threshold=0.001f, float ki=0.04f, CORENE_DETECTOR_TYPE type=CD_NOBLE)
HarrisCornerDetector.
Definition: harris_corner_detector.hpp:102
float * getMinVal(BBox *box, float *ret)
getMinVal computes the minimum value for the current Image.
int radius
Definition: harris_corner_detector.hpp:63
The HarrisCornerDetector class.
Definition: harris_corner_detector.hpp:54
static Image * execute(Image *imgIn, Image *imgOut, LUMINANCE_TYPE type=LT_CIE_LUMINANCE)
execute
Definition: filter_luminance.hpp:166
Image * Process(ImageVec imgIn, Image *imgOut)
Process.
Definition: filter_npasses.hpp:310
The GeneralCornerDetector class.
Definition: general_corner_detector.hpp:42
void setNULL()
setNULL
Definition: harris_corner_detector.hpp:83
float threshold
Definition: harris_corner_detector.hpp:62
static Image * execute(Image *imgIn, Image *imgOut, int size)
execute
Definition: filter_max.hpp:101
The Image class stores an image as buffer of float.
Definition: image.hpp:60
Image * clone() const
Clone creates a deep copy of the calling instance.
Definition: harris_corner_detector.hpp:47
Image * allocateSimilarOne()
allocateSimilarOne creates an Image with similar size of the calling instance.
int height
Definition: harris_corner_detector.hpp:67
#define CLAMPi(x, a, b)
Definition: math.hpp:81
CORENE_DETECTOR_TYPE
Definition: harris_corner_detector.hpp:47
PIC_INLINE ImageVec Single(Image *img)
Single creates an std::vector which contains img; this is for filters input.
Definition: image_vec.hpp:36
Definition: bilateral_separation.hpp:25
Image * lum
Definition: general_corner_detector.hpp:45
Image * ret
Definition: harris_corner_detector.hpp:59
Image * I_grad_flt
Definition: harris_corner_detector.hpp:58
float ki
Definition: harris_corner_detector.hpp:62
Image * I_grad
Definition: harris_corner_detector.hpp:57
The FilterGaussian2D class.
Definition: filter_gaussian_2d.hpp:31
float * getMaxVal(BBox *box, float *ret)
getMaxVal computes the maximum value for the current Image.
Definition: harris_corner_detector.hpp:47
int width
Definition: image.hpp:80
Definition: harris_corner_detector.hpp:47
int height
Definition: image.hpp:80
static void sortCornersAndTransfer(std::vector< Eigen::Vector3f > *corners, std::vector< Eigen::Vector2f > *cornersOut, int nBestPoints=-1, bool bDescend=true)
sortCornersAndTransfer
Definition: general_corner_detector.hpp:127
int width
Definition: harris_corner_detector.hpp:67