hash.cpp
Go to the documentation of this file.
00001 #include <ros/ros.h>
00002 #include "libhaloc/hash.h"
00003 #include <opencv2/core/eigen.hpp>
00004 
00005 
00008 haloc::Hash::Params::Params() :
00009   num_proj(DEFAULT_NUM_PROJ)
00010 {}
00011 
00014 haloc::Hash::Hash()
00015 {
00016   // Initializations
00017   h_size_ = -1;
00018   initialized_ = false;
00019 }
00020 
00024 bool haloc::Hash::isInitialized()
00025 {
00026   return initialized_;
00027 }
00028 
00033 void haloc::Hash::setParams(const Params& params)
00034 {
00035   params_ = params;
00036 }
00037 
00038 // Class initialization
00039 void haloc::Hash::init(Mat desc)
00040 {
00041   // Create the random projections vectors
00042   initProjections(desc.rows);
00043 
00044   // Set the size of the descriptors
00045   h_size_ = params_.num_proj * desc.cols;
00046 
00047   // Set initialized to true
00048   initialized_ = true;
00049 }
00050 
00055 vector<float> haloc::Hash::getHash(Mat desc)
00056 {
00057   // Initialize the histogram with 0's
00058   vector<float> hash(h_size_, 0.0);
00059 
00060   // Sanity check
00061   if (desc.rows == 0) return hash;
00062 
00063   // Project the descriptors
00064   uint k = 0;
00065   for (uint i=0; i<r_.size(); i++)
00066   {
00067     for (int n=0; n<desc.cols; n++)
00068     {
00069       float desc_sum = 0.0;
00070       for (uint m=0; m<desc.rows; m++)
00071         desc_sum += r_[i][m]*desc.at<float>(m, n);
00072 
00073       hash[k] = desc_sum/(float)desc.rows;
00074       k++;
00075     }
00076   }
00077 
00078   return hash;
00079 }
00080 
00086 void haloc::Hash::initProjections(int desc_size)
00087 {
00088   // Initializations
00089   int seed = time(NULL);
00090   r_.clear();
00091 
00092   // The size of the descriptors may vary... We multiply the current descriptor size
00093   // for a scalar to handle the larger cases.
00094   int v_size = 6*desc_size;
00095 
00096   // We will generate N-orthogonal vectors creating a linear system of type Ax=b.
00097   // Generate a first random vector
00098   vector<float> r = compute_random_vector(seed, v_size);
00099   r_.push_back(unit_vector(r));
00100 
00101   // Generate the set of orthogonal vectors
00102   for (uint i=1; i<params_.num_proj; i++)
00103   {
00104     // Generate a random vector of the correct size
00105     vector<float> new_v = compute_random_vector(seed + i, v_size - i);
00106 
00107     // Get the right terms (b)
00108     VectorXf b(r_.size());
00109     for (uint n=0; n<r_.size(); n++)
00110     {
00111       vector<float> cur_v = r_[n];
00112       float sum = 0.0;
00113       for (uint m=0; m<new_v.size(); m++)
00114       {
00115         sum += new_v[m]*cur_v[m];
00116       }
00117       b(n) = -sum;
00118     }
00119 
00120     // Get the matrix of equations (A)
00121     MatrixXf A(i, i);
00122     for (uint n=0; n<r_.size(); n++)
00123     {
00124       uint k=0;
00125       for (uint m=r_[n].size()-i; m<r_[n].size(); m++)
00126       {
00127         A(n,k) = r_[n][m];
00128         k++;
00129       }
00130     }
00131 
00132     // Apply the solver
00133     VectorXf x = A.colPivHouseholderQr().solve(b);
00134 
00135     // Add the solutions to the new vector
00136     for (uint n=0; n<r_.size(); n++)
00137       new_v.push_back(x(n));
00138     new_v = unit_vector(new_v);
00139 
00140     // Push the new vector
00141     r_.push_back(new_v);
00142   }
00143 }
00144 
00150 vector<float> haloc::Hash::compute_random_vector(uint seed, int size)
00151 {
00152   srand(seed);
00153   vector<float> h;
00154   for (int i=0; i<size; i++)
00155     h.push_back( (float)rand()/RAND_MAX );
00156   return h;
00157 }
00158 
00163 vector<float> haloc::Hash::unit_vector(vector<float> x)
00164 {
00165   // Compute the norm
00166   float sum = 0.0;
00167   for (uint i=0; i<x.size(); i++)
00168     sum += pow(x[i], 2.0);
00169   float x_norm = sqrt(sum);
00170 
00171   // x^ = x/|x|
00172   for (uint i=0; i<x.size(); i++)
00173     x[i] = x[i] / x_norm;
00174 
00175   return x;
00176 }
00177 
00183 float haloc::Hash::match(vector<float> hash_1, vector<float> hash_2)
00184 {
00185   // Compute the distance
00186   float sum = 0.0;
00187   for (uint i=0; i<hash_1.size(); i++)
00188     sum += fabs(hash_1[i] - hash_2[i]);
00189 
00190   return sum;
00191 }


libhaloc
Author(s): Pep Lluis Negre
autogenerated on Thu Jun 6 2019 21:25:00