[arrayfire] 101/248: Added CPU implementation of GLOH
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Tue Nov 17 15:54:09 UTC 2015
This is an automated email from the git hooks/post-receive script.
ghisvail-guest pushed a commit to branch dfsg-clean
in repository arrayfire.
commit 97dae2ed2a26039444cbbfa35a71e99eca7338f8
Author: Peter Andreas Entschev <peter at arrayfire.com>
Date: Wed Oct 7 16:15:29 2015 -0400
Added CPU implementation of GLOH
---
src/backend/cpu/sift.cpp | 13 ++-
src/backend/cpu/sift.hpp | 3 +-
src/backend/cpu/sift_nonfree.hpp | 185 ++++++++++++++++++++++++++++++++++++---
3 files changed, 184 insertions(+), 17 deletions(-)
diff --git a/src/backend/cpu/sift.cpp b/src/backend/cpu/sift.cpp
index 1f38fff..d6027d7 100644
--- a/src/backend/cpu/sift.cpp
+++ b/src/backend/cpu/sift.cpp
@@ -36,14 +36,18 @@ unsigned sift(Array<float>& x, Array<float>& y, Array<float>& score,
const Array<T>& in, const unsigned n_layers,
const float contrast_thr, const float edge_thr,
const float init_sigma, const bool double_input,
- const float img_scale, const float feature_ratio)
+ const float img_scale, const float feature_ratio,
+ const bool compute_GLOH)
{
#ifdef AF_BUILD_SIFT
return sift_impl<T, convAccT>(x, y, score, ori, size, desc, in, n_layers,
contrast_thr, edge_thr, init_sigma, double_input,
- img_scale, feature_ratio);
+ img_scale, feature_ratio, compute_GLOH);
#else
- AF_ERROR("ArrayFire was not built with nonfree support, SIFT disabled\n", AFF_ERR_NONFREE);
+ if (compute_GLOH)
+ AF_ERROR("ArrayFire was not built with nonfree support, GLOH disabled\n", AFF_ERR_NONFREE);
+ else
+ AF_ERROR("ArrayFire was not built with nonfree support, SIFT disabled\n", AFF_ERR_NONFREE);
#endif
}
@@ -54,7 +58,8 @@ unsigned sift(Array<float>& x, Array<float>& y, Array<float>& score,
const Array<T>& in, const unsigned n_layers, \
const float contrast_thr, const float edge_thr, \
const float init_sigma, const bool double_input, \
- const float img_scale, const float feature_ratio);
+ const float img_scale, const float feature_ratio, \
+ const bool compute_GLOH);
INSTANTIATE(float , float )
INSTANTIATE(double, double)
diff --git a/src/backend/cpu/sift.hpp b/src/backend/cpu/sift.hpp
index 044b4e0..1ceea4b 100644
--- a/src/backend/cpu/sift.hpp
+++ b/src/backend/cpu/sift.hpp
@@ -21,6 +21,7 @@ unsigned sift(Array<float>& x, Array<float>& y, Array<float>& score,
const Array<T>& in, const unsigned n_layers,
const float contrast_thr, const float edge_thr,
const float init_sigma, const bool double_input,
- const float img_scale, const float feature_ratio);
+ const float img_scale, const float feature_ratio,
+ const bool compute_GLOH);
}
diff --git a/src/backend/cpu/sift_nonfree.hpp b/src/backend/cpu/sift_nonfree.hpp
index 6b4ef71..2a123f8 100644
--- a/src/backend/cpu/sift_nonfree.hpp
+++ b/src/backend/cpu/sift_nonfree.hpp
@@ -117,6 +117,18 @@ namespace cpu
// factor used to convert floating-point descriptor to unsigned char
static const float IntDescrFctr = 512.f;
+// Number of GLOH bins in radial direction
+ static const unsigned GLOHRadialBins = 3;
+
+// Radiuses of GLOH descriptors
+ static const float GLOHRadii[GLOHRadialBins] = {6.f, 11.f, 15.f};
+
+// Number of GLOH angular bins (excluding the inner-most radial section)
+ static const unsigned GLOHAngularBins = 8;
+
+// Number of GLOH bins per histogram in descriptor
+ static const unsigned GLOHHistBins = 16;
+
typedef struct
{
float f[4];
@@ -639,9 +651,8 @@ namespace cpu
int radius = hist_width * sqrt(2.f) * (d + 1.f) * 0.5f + 0.5f;
int len = radius*2+1;
- const int histlen = d*d*n;
- for (int i = 0; i < histlen; i++)
+ for (int i = 0; i < desc_len; i++)
desc[i] = 0.f;
// Calculate orientation histogram
@@ -700,15 +711,154 @@ namespace cpu
}
}
- normalizeDesc(desc, histlen);
+ normalizeDesc(desc, desc_len);
+
+ for (int i = 0; i < desc_len; i++)
+ desc[i] = min(desc[i], DescrMagThr);
+
+ normalizeDesc(desc, desc_len);
+
+ // Calculate final descriptor values
+ for (int k = 0; k < desc_len; k++) {
+ desc_out[f*desc_len+k] = round(min(255.f, desc[k] * IntDescrFctr));
+ }
+ }
+ }
+
+// Computes GLOH feature descriptors for features in an array. Based on Section III-B
+// of Mikolajczyk and Schmid paper.
+ template<typename T>
+ void computeGLOHDescriptor(
+ float* desc_out,
+ const unsigned desc_len,
+ const float* x_in,
+ const float* y_in,
+ const unsigned* layer_in,
+ const float* response_in,
+ const float* size_in,
+ const float* ori_in,
+ const unsigned total_feat,
+ const std::vector< Array<T> >& gauss_pyr,
+ const int d,
+ const unsigned rb,
+ const unsigned ab,
+ const unsigned hb,
+ const float scale,
+ const unsigned octave,
+ const unsigned n_layers)
+ {
+ float desc[272];
+
+ for (unsigned f = 0; f < total_feat; f++) {
+ const unsigned layer = layer_in[f];
+ float ori = (360.f - ori_in[f]) * PI_VAL / 180.f;
+ ori = (ori > PI_VAL) ? ori - PI_VAL*2 : ori;
+ const float size = size_in[f];
+ const int fx = round(x_in[f] * scale);
+ const int fy = round(y_in[f] * scale);
+
+ // Points img to correct Gaussian pyramid layer
+ Array<T> img = gauss_pyr[octave*(n_layers+3) + layer];
+ const T* img_ptr = img.get();
+ af::dim4 idims = img.dims();
+
+ float cos_t = cos(ori);
+ float sin_t = sin(ori);
+ float hist_bins_per_rad = hb / (PI_VAL * 2.f);
+ float polar_bins_per_rad = ab / (PI_VAL * 2.f);
+ float exp_denom = GLOHRadii[rb-1] * 0.5f;
+
+ float hist_width = DescrSclFctr * size * scale * 0.5f;
+
+ // Keep same descriptor radius used for SIFT
+ int radius = hist_width * sqrt(2.f) * (d + 1.f) * 0.5f + 0.5f;
+
+ // Alternative radius size calculation, changing the radius weight
+ // (rw) in the range of 0.25f-0.75f gives different results,
+ // increasing it tends to show a better recall rate but with a
+ // smaller amount of correct matches
+ //float rw = 0.5f;
+ //int radius = hist_width * GLOHRadii[rb-1] * rw + 0.5f;
+
+ int len = radius*2+1;
+
+ for (int i = 0; i < desc_len; i++)
+ desc[i] = 0.f;
+
+ // Calculate orientation histogram
+ for (int l = 0; l < len*len; l++) {
+ int i = l / len - radius;
+ int j = l % len - radius;
+
+ int y = fy + i;
+ int x = fx + j;
+
+ float x_rot = (j * cos_t - i * sin_t);
+ float y_rot = (j * sin_t + i * cos_t);
+
+ float r = sqrt(x_rot*x_rot + y_rot*y_rot) / radius * GLOHRadii[rb-1];
+ float theta = atan2(y_rot, x_rot);
+ while (theta < 0.0f)
+ theta += PI_VAL*2;
+ while (theta >= PI_VAL*2)
+ theta -= PI_VAL*2;
+
+ float tbin = theta * polar_bins_per_rad;
+ float rbin = (r < GLOHRadii[0]) ? r / GLOHRadii[0] :
+ ((r < GLOHRadii[1]) ? 1 + (r - GLOHRadii[0]) / (float)(GLOHRadii[1] - GLOHRadii[0]) :
+ min(2 + (r - GLOHRadii[1]) / (float)(GLOHRadii[2] - GLOHRadii[1]), 3.f-FLT_EPSILON));
+
+ if (r <= GLOHRadii[rb-1] &&
+ y > 0 && y < idims[0] - 1 && x > 0 && x < idims[1] - 1) {
+ float dx = (float)(IPTR(x+1, y) - IPTR(x-1, y));
+ float dy = (float)(IPTR(x, y-1) - IPTR(x, y+1));
+
+ float grad_mag = sqrt(dx*dx + dy*dy);
+ float grad_ori = atan2(dy, dx) - ori;
+ while (grad_ori < 0.0f)
+ grad_ori += PI_VAL*2;
+ while (grad_ori >= PI_VAL*2)
+ grad_ori -= PI_VAL*2;
+
+ float w = exp(-r / exp_denom);
+ float obin = grad_ori * hist_bins_per_rad;
+ float mag = grad_mag*w;
+
+ int t0 = floor(tbin);
+ int r0 = floor(rbin);
+ int o0 = floor(obin);
+ tbin -= t0;
+ rbin -= r0;
+ obin -= o0;
+
+ for (int rl = 0; rl <= 1; rl++) {
+ int rb = (rbin > 0.5f) ? (r0 + rl) : (r0 - rl);
+ float v_r = mag * ((rl == 0) ? 1.0f - rbin : rbin);
+ if (rb >= 0 && rb <= 2) {
+ for (int tl = 0; tl <= 1; tl++) {
+ int tb = (t0 + tl) % ab;
+ float v_t = v_r * ((tl == 0) ? 1.0f - tbin : tbin);
+ for (int ol = 0; ol <= 1; ol++) {
+ int ob = (o0 + ol) % hb;
+ float v_o = v_t * ((ol == 0) ? 1.0f - obin : obin);
+ unsigned idx = (rb > 0) * (hb + ((rb-1) * ab + tb)*hb) + ob;
+ desc[idx] += v_o;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ normalizeDesc(desc, desc_len);
- for (int i = 0; i < d*d*n; i++)
+ for (int i = 0; i < desc_len; i++)
desc[i] = min(desc[i], DescrMagThr);
- normalizeDesc(desc, histlen);
+ normalizeDesc(desc, desc_len);
// Calculate final descriptor values
- for (int k = 0; k < d*d*n; k++) {
+ for (int k = 0; k < desc_len; k++) {
desc_out[f*desc_len+k] = round(min(255.f, desc[k] * IntDescrFctr));
}
}
@@ -815,7 +965,8 @@ namespace cpu
const Array<T>& in, const unsigned n_layers,
const float contrast_thr, const float edge_thr,
const float init_sigma, const bool double_input,
- const float img_scale, const float feature_ratio)
+ const float img_scale, const float feature_ratio,
+ const bool compute_GLOH)
{
af::dim4 idims = in.dims();
@@ -840,7 +991,10 @@ namespace cpu
const unsigned d = DescrWidth;
const unsigned n = DescrHistBins;
- const unsigned desc_len = d*d*n;
+ const unsigned rb = GLOHRadialBins;
+ const unsigned ab = GLOHAngularBins;
+ const unsigned hb = GLOHHistBins;
+ const unsigned desc_len = (compute_GLOH) ? (1 + (rb-1) * ab) * hb : d*d*n;
for (unsigned i = 0; i < n_octaves; i++) {
af::dim4 ddims = dog_pyr[i*(n_layers+2)].dims();
@@ -966,10 +1120,17 @@ namespace cpu
float scale = 1.f/(1 << i);
if (double_input) scale *= 2.f;
- computeDescriptor<T>(desc, desc_len,
- oriented_x, oriented_y, oriented_layer,
- oriented_response, oriented_size, oriented_ori,
- oriented_feat, gauss_pyr, d, n, scale, i, n_layers);
+ if (compute_GLOH)
+ computeGLOHDescriptor<T>(desc, desc_len,
+ oriented_x, oriented_y, oriented_layer,
+ oriented_response, oriented_size, oriented_ori,
+ oriented_feat, gauss_pyr, d, rb, ab, hb,
+ scale, i, n_layers);
+ else
+ computeDescriptor<T>(desc, desc_len,
+ oriented_x, oriented_y, oriented_layer,
+ oriented_response, oriented_size, oriented_ori,
+ oriented_feat, gauss_pyr, d, n, scale, i, n_layers);
total_feat += oriented_feat;
feat_pyr[i] = oriented_feat;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/arrayfire.git
More information about the debian-science-commits
mailing list