// Copyright (C) 2013 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_BINNED_VECTOR_IMAGE_FEATUrES_Hh_
#define DLIB_BINNED_VECTOR_IMAGE_FEATUrES_Hh_
#include "../lsh/projection_hash.h"
#include "binned_vector_feature_image_abstract.h"
#include <vector>
#include "../algs.h"
#include "../matrix.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type_ = projection_hash
>
class binned_vector_feature_image : noncopyable
{
public:
typedef feature_extractor feature_extractor_type;
typedef hash_function_type_ hash_function_type;
typedef std::vector<std::pair<unsigned int,double> > descriptor_type;
binned_vector_feature_image (
);
void clear (
);
void set_hash (
const hash_function_type& hash_
);
const hash_function_type& get_hash (
) const;
void copy_configuration (
const feature_extractor& item
);
void copy_configuration (
const binned_vector_feature_image& item
);
template <
typename image_type
>
inline void load (
const image_type& img
);
inline size_t size (
) const;
inline long nr (
) const;
inline long nc (
) const;
inline long get_num_dimensions (
) const;
inline const descriptor_type& operator() (
long row,
long col
) const;
inline const rectangle get_block_rect (
long row,
long col
) const;
inline const point image_to_feat_space (
const point& p
) const;
inline const rectangle image_to_feat_space (
const rectangle& rect
) const;
inline const point feat_to_image_space (
const point& p
) const;
inline const rectangle feat_to_image_space (
const rectangle& rect
) const;
template <typename T>
friend void serialize (
const binned_vector_feature_image<T>& item,
std::ostream& out
);
template <typename T>
friend void deserialize (
binned_vector_feature_image<T>& item,
std::istream& in
);
private:
array2d<descriptor_type> feats;
feature_extractor fe;
hash_function_type phash;
};
// ----------------------------------------------------------------------------------------
template <typename T>
void serialize (
const binned_vector_feature_image<T>& item,
std::ostream& out
)
{
int version = 1;
serialize(version, out);
serialize(item.feats, out);
serialize(item.fe, out);
serialize(item.phash, out);
}
template <typename T>
void deserialize (
binned_vector_feature_image<T>& item,
std::istream& in
)
{
int version = 0;
deserialize(version, in);
if (version != 1)
throw dlib::serialization_error("Unexpected version found while deserializing dlib::binned_vector_feature_image");
deserialize(item.feats, in);
deserialize(item.fe, in);
deserialize(item.phash, in);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// binned_vector_feature_image member functions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
binned_vector_feature_image<feature_extractor,hash_function_type>::
binned_vector_feature_image (
)
{
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
void binned_vector_feature_image<feature_extractor,hash_function_type>::
clear (
)
{
fe.clear();
phash = hash_function_type();
feats.clear();
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
void binned_vector_feature_image<feature_extractor,hash_function_type>::
set_hash (
const hash_function_type& hash_
)
{
phash = hash_;
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
const hash_function_type& binned_vector_feature_image<feature_extractor,hash_function_type>::
get_hash (
) const
{
return phash;
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
void binned_vector_feature_image<feature_extractor,hash_function_type>::
copy_configuration (
const feature_extractor& item
)
{
fe.copy_configuration(item);
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
void binned_vector_feature_image<feature_extractor,hash_function_type>::
copy_configuration (
const binned_vector_feature_image& item
)
{
fe.copy_configuration(item.fe);
phash = item.phash;
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
template <
typename image_type
>
void binned_vector_feature_image<feature_extractor,hash_function_type>::
load (
const image_type& img
)
{
fe.load(img);
if (fe.size() != 0)
{
feats.set_size(fe.nr(), fe.nc());
for (long r = 0; r < feats.nr(); ++r)
{
for (long c = 0; c < feats.nc(); ++c)
{
feats[r][c].clear();
feats[r][c].reserve(fe.get_num_dimensions()+1);
const typename feature_extractor::descriptor_type& des = fe(r,c);
const unsigned long idx = phash(des);
const unsigned long offset = idx*(fe.get_num_dimensions()+1);
for (long i = 0; i < des.size(); ++i)
{
feats[r][c].push_back(std::make_pair(offset + i, des(i)));
}
feats[r][c].push_back(std::make_pair(offset + des.size(), 1.0));
}
}
}
else
{
feats.set_size(0,0);
}
fe.unload();
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
size_t binned_vector_feature_image<feature_extractor,hash_function_type>::
size (
) const
{
return feats.size();
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
long binned_vector_feature_image<feature_extractor,hash_function_type>::
nr (
) const
{
return feats.nr();
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
long binned_vector_feature_image<feature_extractor,hash_function_type>::
nc (
) const
{
return feats.nc();
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
long binned_vector_feature_image<feature_extractor,hash_function_type>::
get_num_dimensions (
) const
{
return phash.num_hash_bins()*(fe.get_num_dimensions()+1);
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
const std::vector<std::pair<unsigned int,double> >& binned_vector_feature_image<feature_extractor,hash_function_type>::
operator() (
long row,
long col
) const
{
// make sure requires clause is not broken
DLIB_ASSERT(0 <= row && row < nr() &&
0 <= col && col < nc(),
"\t descriptor_type binned_vector_feature_image::operator(row,col)"
<< "\n\t Invalid inputs were given to this function"
<< "\n\t row: " << row
<< "\n\t col: " << col
<< "\n\t nr(): " << nr()
<< "\n\t nc(): " << nc()
<< "\n\t this: " << this
);
return feats[row][col];
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
const rectangle binned_vector_feature_image<feature_extractor,hash_function_type>::
get_block_rect (
long row,
long col
) const
{
return fe.get_block_rect(row,col);
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
const point binned_vector_feature_image<feature_extractor,hash_function_type>::
image_to_feat_space (
const point& p
) const
{
return fe.image_to_feat_space(p);
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
const rectangle binned_vector_feature_image<feature_extractor,hash_function_type>::
image_to_feat_space (
const rectangle& rect
) const
{
return fe.image_to_feat_space(rect);
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
const point binned_vector_feature_image<feature_extractor,hash_function_type>::
feat_to_image_space (
const point& p
) const
{
return fe.feat_to_image_space(p);
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor,
typename hash_function_type
>
const rectangle binned_vector_feature_image<feature_extractor,hash_function_type>::
feat_to_image_space (
const rectangle& rect
) const
{
return fe.feat_to_image_space(rect);
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_BINNED_VECTOR_IMAGE_FEATUrES_Hh_