PICCANTE  0.4
The hottest HDR imaging library!
sift_descriptor.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_SIFT_DESCRIPTOR_HPP
19 #define PIC_SIFT_DESCRIPTOR_HPP
20 
21 #include "../image.hpp"
22 #include "../util/array.hpp"
23 
24 namespace pic {
25 
27 {
28 protected:
30 
33 
36 
38 
39 public:
40 
41  SIFTDescriptor(float thr_weak = 0.01f, int patchSize = 16, int subPatchSize = 4, int nBin = 8)
42  {
43  reference_angles = NULL;
45  }
46 
54  void update(float thr_weak = 0.05f, int patchSize = 16, int subPatchSize = 4, int nBin = 8)
55  {
56  thr_weak = MAX(thr_weak, 0.05f);
57  nBin = MAX(nBin, 4);
58 
59  this->thr_weak = thr_weak;
60  this->nBin = nBin;
61 
63  this->patchSize = (half_patchSize << 1) + 1;
64  this->subPatchSize = subPatchSize;
65 
68 
69  sigma = float(patchSize) * 1.5f;
70  sigma_sq_2 = sigma * sigma * 2.0f;
71 
73  reference_angles = new float[nBin];
74  nBinf = float(nBin);
75 
76  for(int i = 0; i < nBin; i++) {
77  reference_angles[i] = (float(i) * C_PI_2) / nBinf;
78  }
79  sector_angle = C_PI_2 / float(nBin);
80 
81  for(int i = 0; i < 36; i++) {
82  reference_angles_orientation[i] = (float(i) * C_PI_2) / 36.0f;
83  }
85 
86  }
87 
93  {
94  return tot;
95  }
96 
104  float computePatchOrientation(Image *imgGrad, int x0, int y0)
105  {
106  float orientation[36];
107  Arrayf::assign(0.0f, orientation, 36);
108 
109  int nBin = 36;
110  float nBinf = float(nBin);
111 
112  for(int i = 0; i < patchSize; i ++) {
113  int y_local = i - half_patchSize;
114  int y = y_local + y0;
115 
116  for(int j = 0; j < patchSize; j ++) {
117  int x_local = j - half_patchSize;
118  int x = x_local + x0;
119 
120  float *grad = (*imgGrad)(x, y);
121 
122  //compute current (x,y) angle
123  float angle = atan2f(grad[1], grad[0]);
124  angle = (angle >= 0.0f) ? angle : angle + C_PI_2;
125  angle = CLAMPi(angle, 0.0f, C_PI_2);
126 
127  //place it in the bin
128  float index_f = nBinf * (angle / C_PI_2);
129  int index = int(floorf(index_f));
130  int index_1 = (index + 1) % nBin;
131 
132  float dist = (angle - reference_angles_orientation[index]) / sector_angle_orientation;
133  dist = CLAMPi(dist, 0.0f, 1.0f);
134 
135  int squared = x_local * x_local + y_local * y_local;
136 
137  float mag = grad[2] * expf(-float(squared) / sigma_sq_2);
138 
139  orientation[index] += mag * (1.0f - dist);
140  orientation[index_1] += mag * dist;
141  }
142  }
143 
144  int index;
145  Arrayf::getMax(orientation, 36, index);
146 
147  return reference_angles_orientation[index];
148  }
149 
158  float *get(Image *imgGrad, int x0, int y0, float *desc = NULL)
159  {
160  if(imgGrad == NULL) {
161  return desc;
162  }
163 
164  if(desc == NULL) {
165  desc = new float[tot];
166  }
167 
168  memset(desc, 0, sizeof(float) * tot);
169 
170  float kp_angle = computePatchOrientation(imgGrad, x0, y0);
171 
172  float cosAngle = cosf(-kp_angle);
173  float sinAngle = sinf(-kp_angle);
174 
175  //compute the descriptor
176  int counter = 0;
177 
178  for(int i = 0; i < patchSize; i += subPatchSize) {
179  int tmp_y = y0 + i - half_patchSize;
180 
181  for(int j = 0; j < patchSize; j += subPatchSize) {
182  int tmp_x = x0 + j - half_patchSize;
183 
184  for(int k = 0; k < subPatchSize; k++) {
185  int y = tmp_y + k;
186 
187  for(int l = 0; l < subPatchSize; l++) {
188  int x = tmp_x + l;
189 
190  float *grad = (*imgGrad)(x, y);
191 
192  if(grad[2] <= thr_weak) {
193  continue;
194  }
195 
196  //rotate gradients according to the patch's main orientation
197  float r_gx = grad[0] * cosAngle - grad[1] * sinAngle;
198  float r_gy = grad[0] * sinAngle + grad[1] * cosAngle;
199 
200  float angle = atan2f(r_gy, r_gx);
201  angle = (angle >= 0.0f) ? angle : angle + C_PI_2;
202  angle = CLAMPi(angle, 0.0f, C_PI_2);
203 
204  //find the bin
205  float index_f = nBinf * (angle / C_PI_2);
206  int index = int(floorf(index_f));
207  int index_1 = (index + 1) % nBin;
208 
209  float dist = (angle - reference_angles[index]) / sector_angle;
210  dist = CLAMPi(dist, 0.0f, 1.0f);
211 
212  int y_local = i + k - half_patchSize;
213  int x_local = j + l - half_patchSize;
214  int squared = x_local * x_local + y_local * y_local;
215 
216  float mag = grad[2] * expf(-float(squared) / sigma_sq_2);
217 
218  desc[counter + index] += mag * (1.0f - dist);
219  desc[counter + index_1] += mag * dist;
220  }
221 
222  }
223 
224  counter += nBin;
225  }
226  }
227 
228  //normalize desc
230 
231  //remove strong edges; i.e., over 0.2
232  for(int i = 0; i < tot; i++) {
233  desc[i] = desc[i] > 0.2f ? desc[i] : 0.2f;
234  }
235 
236  //re-normalize desc
238 
239  return desc;
240  }
241 
242  /***match: matches two descriptors*/
243  static float match(float *fv0, float *fv1, int nfv)
244  {
245  if(fv0 == NULL || fv1 == NULL || nfv < 1) {
246  return -1.0f;
247  }
248 
249  return Array<float>::distanceSq(fv0, fv1, nfv);
250  }
251 };
252 
253 } // end namespace NSF
254 
255 #endif /* NSF_SIFT_DESCRIPTOR_HPP */
256 
int half_patchSize
Definition: sift_descriptor.hpp:37
static T getMax(T *data, int size, int &ind)
getMax
Definition: array.hpp:516
float computePatchOrientation(Image *imgGrad, int x0, int y0)
computePatchOrientation
Definition: sift_descriptor.hpp:104
void update(float thr_weak=0.05f, int patchSize=16, int subPatchSize=4, int nBin=8)
update
Definition: sift_descriptor.hpp:54
static float normalize(float *data, int n, float norm_sq=-1.0f)
normalize
Definition: array.hpp:257
static float match(float *fv0, float *fv1, int nfv)
Definition: sift_descriptor.hpp:243
float sigma
Definition: sift_descriptor.hpp:29
int getDescriptorSize()
getDescriptorSize returns the descriptor size.
Definition: sift_descriptor.hpp:92
int subPatchSize
Definition: sift_descriptor.hpp:37
T * delete_vec_s(T *data)
delete_vec_s
Definition: std_util.hpp:138
static T distanceSq(T *data0, T *data1, int n)
distanceSq
Definition: array.hpp:195
const float C_PI_2
Definition: math.hpp:52
Definition: sift_descriptor.hpp:26
float sector_angle
Definition: sift_descriptor.hpp:32
float sigma_sq_2
Definition: sift_descriptor.hpp:29
SIFTDescriptor(float thr_weak=0.01f, int patchSize=16, int subPatchSize=4, int nBin=8)
Definition: sift_descriptor.hpp:41
float thr_weak
Definition: sift_descriptor.hpp:29
int patchSize
Definition: sift_descriptor.hpp:37
The Image class stores an image as buffer of float.
Definition: image.hpp:60
int subPatchSize_sq
Definition: sift_descriptor.hpp:37
#define CLAMPi(x, a, b)
Definition: math.hpp:81
Definition: bilateral_separation.hpp:25
static T * assign(T *data, int size, T *ret)
assign
Definition: array.hpp:464
#define MAX(a, b)
Definition: math.hpp:73
float * reference_angles
Definition: sift_descriptor.hpp:31
float reference_angles_orientation[36]
Definition: sift_descriptor.hpp:34
float nBinf
Definition: sift_descriptor.hpp:32
float sector_angle_orientation
Definition: sift_descriptor.hpp:35
int tot
Definition: sift_descriptor.hpp:37
int nBin
Definition: sift_descriptor.hpp:37