31 ASSERT_(options.SpinImagesOptions.radius > 1);
39 const unsigned int HIST_N_INT =
40 options.SpinImagesOptions.hist_size_intensity;
41 const unsigned int HIST_N_DIS =
42 options.SpinImagesOptions.hist_size_distance;
43 const unsigned int R = options.SpinImagesOptions.radius;
44 const int img_w =
static_cast<int>(in_img.
getWidth());
45 const int img_h =
static_cast<int>(in_img.
getHeight());
46 const bool img_color = in_img.
isColor();
50 const float k_int2idx = (HIST_N_INT - 1) / 255.0f;
51 const float k_idx2int = 1.0f / k_int2idx;
55 const float k_dis2idx = (HIST_N_DIS - 1) /
static_cast<float>(
R);
56 const float k_idx2dis = 1.0f / k_dis2idx;
60 const int STD_TIMES = 2;
61 const int kernel_size_dist =
static_cast<int>(
62 ceil(k_dis2idx * STD_TIMES * options.SpinImagesOptions.std_dist));
64 const float _2var_int =
65 -1.0f / (2 *
square(options.SpinImagesOptions.std_intensity));
66 const float _2var_dist =
67 -1.0f / (2 *
square(options.SpinImagesOptions.std_dist));
74 it != in_features.
end(); ++it)
77 (*it)->scale = options.SpinImagesOptions.radius;
84 int px0 =
round((*it)->x -
R);
85 int px1 =
round((*it)->x +
R);
86 int py0 =
round((*it)->y -
R);
87 int py1 =
round((*it)->y +
R);
91 px1 =
min(img_w - 1, px1);
93 py1 =
min(img_h - 1, py1);
98 for (
int px = px0; px <= px1; px++)
100 for (
int py = py0; py <= py1; py++)
109 (aux_pix_ptr[0] + aux_pix_ptr[1] + aux_pix_ptr[2]) / 3;
112 const float pix_dist = hypot((*it)->x - px, (*it)->y - py);
113 const int center_bin_dist = k_dis2idx * pix_dist;
123 const int bin_int = k_int2idx * pix_val;
125 if (center_bin_dist<
static_cast<int>(HIST_N_DIS))
127 hist2d(bin_int,center_bin_dist) +=1;
134 const int bin_int_low = max(
140 options.SpinImagesOptions.std_intensity))));
141 const int bin_int_hi =
min(
142 static_cast<int>(HIST_N_INT - 1),
148 options.SpinImagesOptions.std_intensity))));
152 if (center_bin_dist <
153 static_cast<int>(HIST_N_DIS))
158 const int bin_dist_low =
159 max(0, center_bin_dist - kernel_size_dist);
160 const int bin_dist_hi =
161 min(
static_cast<int>(HIST_N_DIS - 1),
162 center_bin_dist + kernel_size_dist);
164 int bin_dist, bin_int;
165 float pix_dist_cur_dist =
166 pix_dist - bin_dist_low * k_idx2dis;
168 for (bin_dist = bin_dist_low; bin_dist <= bin_dist_hi;
169 bin_dist++, pix_dist_cur_dist -= k_idx2dis)
171 float pix_val_cur_val =
172 pix_val - (bin_int_low * k_idx2int);
174 for (bin_int = bin_int_low; bin_int <= bin_int_hi;
175 bin_int++, pix_val_cur_val -= k_idx2int)
178 double v = _2var_dist *
square(pix_dist_cur_dist) +
179 _2var_int *
square(pix_val_cur_val);
187 hist2d.get_unsafe(bin_int, bin_dist) +=
199 hist2d.normalize(0, 1);
217 std::vector<float>& ptr_trg = (*it)->descriptors.SpinImg;
218 ptr_trg.resize(HIST_N_INT * HIST_N_DIS);
220 for (
unsigned i = 0; i < HIST_N_DIS; i++)
221 for (
unsigned j = 0; j < HIST_N_INT; j++)
222 ptr_trg[idx++] = hist2d.get_unsafe(j, i);
224 (*it)->descriptors.SpinImg_range_rows = HIST_N_DIS;