Skip to content

Commit

Permalink
[features] Use aligned memory for features & descriptors. #511
Browse files Browse the repository at this point in the history
- Enable usage of Eigen function on descriptor arrays.
  • Loading branch information
pmoulon committed Mar 24, 2016
1 parent 7b5c2ee commit 01eec35
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 38 deletions.
5 changes: 1 addition & 4 deletions src/openMVG/features/akaze/msurf_descriptor.hpp
Expand Up @@ -133,10 +133,7 @@ namespace features {
}

// convert to unit vector (L2 norm)
typedef Eigen::Matrix<Real, Eigen::Dynamic, 1> VecReal;
Eigen::Map< VecReal > dataMap( &desc[0], 64);
dataMap.normalize();
//std::cout << dataMap.transpose() << std::endl << std::endl;
desc.normalize();
}

template<typename ImageT>
Expand Down
35 changes: 10 additions & 25 deletions src/openMVG/features/descriptor.hpp
Expand Up @@ -21,30 +21,18 @@ namespace features {
/**
* Class that handle descriptor (a data container of N values of type T).
* SiftDescriptor => <uchar,128> or <float,128>
* Surf 64 => <float,64>
* Brief 512 bits => <unsigned char,512/sizeof(unsigned char)>
*/
template <typename T, std::size_t N>
class Descriptor
class Descriptor : public Eigen::Matrix<T, N, 1>
{
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
typedef T bin_type;
typedef std::size_t size_type;

/// Compile-time length of the descriptor
static const size_type static_size = N;

/// Constructor
inline Descriptor() {}

/// capacity
inline size_type size() const { return N; }

/// Mutable and non-mutable bin getters
inline bin_type& operator[](std::size_t i) { return data[i]; }
inline bin_type operator[](std::size_t i) const { return data[i]; }

inline bin_type* getData() const {return (bin_type* ) (&data[0]);}
static const std::size_t static_size = N;

/// Ostream interface
std::ostream& print(std::ostream& os) const;
Expand All @@ -54,7 +42,7 @@ class Descriptor
template<class Archive>
void save(Archive & archive) const
{
std::vector<T> array(data,data+N);
const std::vector<T> array(this->data(), this->data()+N);
archive( array );
}

Expand All @@ -63,11 +51,8 @@ class Descriptor
{
std::vector<T> array(N);
archive( array );
std::memcpy(data, array.data(), sizeof(T)*N);
std::memcpy(this->data(), array.data(), sizeof(T)*N);
}

private:
bin_type data[N];
};

// Output stream definition
Expand Down Expand Up @@ -122,13 +107,13 @@ inline std::istream& readT<unsigned char>(std::istream& is, unsigned char *tab,
template<typename T, std::size_t N>
std::ostream& Descriptor<T,N>::print(std::ostream& os) const
{
return printT<T>(os, (T*) &data[0], N);
return printT<T>(os, (T*) this->data(), N);
}

template<typename T, std::size_t N>
std::istream& Descriptor<T,N>::read(std::istream& in)
{
return readT<T>(in, (T*) &data[0], N);
return readT<T>(in, (T*) this->data(), N);
}

/// Read descriptors from file
Expand Down Expand Up @@ -187,7 +172,7 @@ static bool loadDescsFromBinFile(
vec_desc.resize(cardDesc);
for (typename DescriptorsT::const_iterator iter = vec_desc.begin();
iter != vec_desc.end(); ++iter) {
fileIn.read((char*) (*iter).getData(),
fileIn.read((char*) (*iter).data(),
VALUE::static_size*sizeof(typename VALUE::bin_type));
}
const bool bOk = !fileIn.bad();
Expand All @@ -211,7 +196,7 @@ static bool saveDescsToBinFile(
file.write((const char*) &cardDesc, sizeof(std::size_t));
for (typename DescriptorsT::const_iterator iter = vec_desc.begin();
iter != vec_desc.end(); ++iter) {
file.write((const char*) (*iter).getData(),
file.write((const char*) (*iter).data(),
VALUE::static_size*sizeof(typename VALUE::bin_type));
}
const bool bOk = file.good();
Expand Down
2 changes: 2 additions & 0 deletions src/openMVG/features/feature.hpp
Expand Up @@ -28,6 +28,8 @@ class PointFeature {
friend std::istream& operator>>(std::istream& in, PointFeature& obj);

public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW

PointFeature(float x=0.0f, float y=0.0f)
: coords_(x, y) {}

Expand Down
4 changes: 2 additions & 2 deletions src/openMVG/features/image_describer_akaze.hpp
Expand Up @@ -224,8 +224,8 @@ class AKAZE_Image_describer : public Image_describer
SIOPointFeature(ptAkaze.x, ptAkaze.y, ptAkaze.size, ptAkaze.angle);

// Compute MLDB descriptor
Descriptor<bool,486> desc;
ComputeMLDBDescriptor(cur_slice.cur, cur_slice.Lx, cur_slice.Ly,
Descriptor<bool,486> desc;
ComputeMLDBDescriptor(cur_slice.cur, cur_slice.Lx, cur_slice.Ly,
ptAkaze.octave, regionsCasted->Features()[i], desc);
// convert the bool vector to the binary unsigned char array
unsigned char * ptr = reinterpret_cast<unsigned char*>(&regionsCasted->Descriptors()[i]);
Expand Down
12 changes: 6 additions & 6 deletions src/openMVG/features/regions.hpp
Expand Up @@ -66,8 +66,8 @@ class Regions

/// Return the squared distance between two descriptors
// A default metric is used according the descriptor type:
// - Scalar: L2,
// - Binary: Hamming
// - Scalar: SquaredL2,
// - Binary: SquaredHamming
virtual double SquaredDescriptorDistance(size_t i, const Regions *, size_t j) const = 0;

/// Add the Inth region to another Region container
Expand Down Expand Up @@ -159,7 +159,7 @@ class Scalar_Regions : public Regions

Regions * EmptyClone() const
{
return new Scalar_Regions();
return new Scalar_Regions;
}

// Return the L2 distance between two descriptors
Expand All @@ -171,7 +171,7 @@ class Scalar_Regions : public Regions

const Scalar_Regions<FeatT, T, L> * regionsT = dynamic_cast<const Scalar_Regions<FeatT, T, L> *>(regions);
static matching::L2_Vectorized<T> metric;
return metric(vec_descs_[i].getData(), regionsT->vec_descs_[j].getData(), DescriptorT::static_size);
return metric(vec_descs_[i].data(), regionsT->vec_descs_[j].data(), DescriptorT::static_size);
}

/// Add the Inth region to another Region container
Expand Down Expand Up @@ -273,7 +273,7 @@ class Binary_Regions : public Regions

Regions * EmptyClone() const
{
return new Binary_Regions();
return new Binary_Regions;
}

// Return the squared Hamming distance between two descriptors
Expand All @@ -286,7 +286,7 @@ class Binary_Regions : public Regions
const Binary_Regions<FeatT, L> * regionsT = dynamic_cast<const Binary_Regions<FeatT, L> *>(regions);
static matching::Hamming<unsigned char> metric;
const typename matching::Hamming<unsigned char>::ResultType descDist =
metric(vec_descs_[i].getData(), regionsT->vec_descs_[j].getData(), DescriptorT::static_size);
metric(vec_descs_[i].data(), regionsT->vec_descs_[j].data(), DescriptorT::static_size);
return descDist * descDist;
}

Expand Down
2 changes: 1 addition & 1 deletion src/software/SfM/main_ComputeFeatures_OpenCV.cpp
Expand Up @@ -107,7 +107,7 @@ class AKAZE_OCV_Image_describer : public Image_describer
SIOPointFeature feat((*i_keypoint).pt.x, (*i_keypoint).pt.y, (*i_keypoint).size, (*i_keypoint).angle);
regionsCasted->Features().push_back(feat);

memcpy(descriptor.getData(),
memcpy(descriptor.data(),
m_desc.ptr<typename DescriptorT::bin_type>(cpt),
DescriptorT::static_size*sizeof(DescriptorT::bin_type));
regionsCasted->Descriptors().push_back(descriptor);
Expand Down

0 comments on commit 01eec35

Please sign in to comment.