519 lines
14 KiB
C++
519 lines
14 KiB
C++
// Copyright (C) 2011 Davis E. King (davis@dlib.net)
|
|
// License: Boost Software License See LICENSE.txt for the full license.
|
|
#ifndef DLIB_HASHED_IMAGE_FEATUrES_Hh_
|
|
#define DLIB_HASHED_IMAGE_FEATUrES_Hh_
|
|
|
|
#include "../lsh/projection_hash.h"
|
|
#include "hashed_feature_image_abstract.h"
|
|
#include <vector>
|
|
#include "../algs.h"
|
|
#include "../matrix.h"
|
|
#include "../statistics.h"
|
|
|
|
namespace dlib
|
|
{
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename feature_extractor,
|
|
typename hash_function_type_ = projection_hash
|
|
>
|
|
class hashed_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;
|
|
|
|
hashed_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 hashed_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;
|
|
|
|
void use_relative_feature_weights (
|
|
);
|
|
|
|
void use_uniform_feature_weights (
|
|
);
|
|
|
|
bool uses_uniform_feature_weights (
|
|
) 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 hashed_feature_image<T>& item,
|
|
std::ostream& out
|
|
);
|
|
|
|
template <typename T>
|
|
friend void deserialize (
|
|
hashed_feature_image<T>& item,
|
|
std::istream& in
|
|
);
|
|
|
|
private:
|
|
|
|
array2d<unsigned long> feats;
|
|
feature_extractor fe;
|
|
hash_function_type phash;
|
|
std::vector<float> feat_counts;
|
|
bool uniform_feature_weights;
|
|
|
|
|
|
// This is a transient variable. It is just here so it doesn't have to be
|
|
// reallocated over and over inside operator()
|
|
mutable descriptor_type hash_feats;
|
|
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <typename T>
|
|
void serialize (
|
|
const hashed_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);
|
|
serialize(item.feat_counts, out);
|
|
serialize(item.uniform_feature_weights, out);
|
|
}
|
|
|
|
template <typename T>
|
|
void deserialize (
|
|
hashed_feature_image<T>& item,
|
|
std::istream& in
|
|
)
|
|
{
|
|
int version = 0;
|
|
deserialize(version, in);
|
|
if (version != 1)
|
|
throw serialization_error("Unexpected version found while deserializing a dlib::hashed_feature_image object.");
|
|
|
|
deserialize(item.feats, in);
|
|
deserialize(item.fe, in);
|
|
deserialize(item.phash, in);
|
|
deserialize(item.feat_counts, in);
|
|
deserialize(item.uniform_feature_weights, in);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
// ----------------------------------------------------------------------------------------
|
|
// hashed_feature_image member functions
|
|
// ----------------------------------------------------------------------------------------
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename feature_extractor,
|
|
typename hash_function_type
|
|
>
|
|
hashed_feature_image<feature_extractor,hash_function_type>::
|
|
hashed_feature_image (
|
|
)
|
|
{
|
|
clear();
|
|
hash_feats.resize(1);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename feature_extractor,
|
|
typename hash_function_type
|
|
>
|
|
void hashed_feature_image<feature_extractor,hash_function_type>::
|
|
clear (
|
|
)
|
|
{
|
|
fe.clear();
|
|
phash = hash_function_type();
|
|
feats.clear();
|
|
feat_counts.clear();
|
|
uniform_feature_weights = false;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename feature_extractor,
|
|
typename hash_function_type
|
|
>
|
|
void hashed_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& hashed_feature_image<feature_extractor,hash_function_type>::
|
|
get_hash (
|
|
) const
|
|
{
|
|
return phash;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename feature_extractor,
|
|
typename hash_function_type
|
|
>
|
|
void hashed_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 hashed_feature_image<feature_extractor,hash_function_type>::
|
|
copy_configuration (
|
|
const hashed_feature_image& item
|
|
)
|
|
{
|
|
fe.copy_configuration(item.fe);
|
|
phash = item.phash;
|
|
uniform_feature_weights = item.uniform_feature_weights;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename feature_extractor,
|
|
typename hash_function_type
|
|
>
|
|
template <
|
|
typename image_type
|
|
>
|
|
void hashed_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());
|
|
feat_counts.assign(phash.num_hash_bins(),1);
|
|
if (uniform_feature_weights)
|
|
{
|
|
for (long r = 0; r < feats.nr(); ++r)
|
|
{
|
|
for (long c = 0; c < feats.nc(); ++c)
|
|
{
|
|
feats[r][c] = phash(fe(r,c));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (long r = 0; r < feats.nr(); ++r)
|
|
{
|
|
for (long c = 0; c < feats.nc(); ++c)
|
|
{
|
|
feats[r][c] = phash(fe(r,c));
|
|
feat_counts[feats[r][c]]++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
feats.set_size(0,0);
|
|
}
|
|
|
|
if (!uniform_feature_weights)
|
|
{
|
|
// use the inverse frequency as the scale for each feature. We also scale
|
|
// these counts so that they are invariant to the size of the image (we scale
|
|
// them so they all look like they come from a 500x400 images).
|
|
const double scale = image_size(img)/(500.0*400.0);
|
|
for (unsigned long i = 0; i < feat_counts.size(); ++i)
|
|
{
|
|
feat_counts[i] = scale/feat_counts[i];
|
|
}
|
|
}
|
|
|
|
fe.unload();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename feature_extractor,
|
|
typename hash_function_type
|
|
>
|
|
size_t hashed_feature_image<feature_extractor,hash_function_type>::
|
|
size (
|
|
) const
|
|
{
|
|
return feats.size();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename feature_extractor,
|
|
typename hash_function_type
|
|
>
|
|
long hashed_feature_image<feature_extractor,hash_function_type>::
|
|
nr (
|
|
) const
|
|
{
|
|
return feats.nr();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename feature_extractor,
|
|
typename hash_function_type
|
|
>
|
|
long hashed_feature_image<feature_extractor,hash_function_type>::
|
|
nc (
|
|
) const
|
|
{
|
|
return feats.nc();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename feature_extractor,
|
|
typename hash_function_type
|
|
>
|
|
long hashed_feature_image<feature_extractor,hash_function_type>::
|
|
get_num_dimensions (
|
|
) const
|
|
{
|
|
return phash.num_hash_bins();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename feature_extractor,
|
|
typename hash_function_type
|
|
>
|
|
void hashed_feature_image<feature_extractor,hash_function_type>::
|
|
use_relative_feature_weights (
|
|
)
|
|
{
|
|
uniform_feature_weights = false;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename feature_extractor,
|
|
typename hash_function_type
|
|
>
|
|
void hashed_feature_image<feature_extractor,hash_function_type>::
|
|
use_uniform_feature_weights (
|
|
)
|
|
{
|
|
uniform_feature_weights = true;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename feature_extractor,
|
|
typename hash_function_type
|
|
>
|
|
bool hashed_feature_image<feature_extractor,hash_function_type>::
|
|
uses_uniform_feature_weights (
|
|
) const
|
|
{
|
|
return uniform_feature_weights;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename feature_extractor,
|
|
typename hash_function_type
|
|
>
|
|
const std::vector<std::pair<unsigned int,double> >& hashed_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 hashed_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
|
|
);
|
|
|
|
hash_feats[0] = std::make_pair(feats[row][col],feat_counts[feats[row][col]]);
|
|
return hash_feats;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename feature_extractor,
|
|
typename hash_function_type
|
|
>
|
|
const rectangle hashed_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 hashed_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 hashed_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 hashed_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 hashed_feature_image<feature_extractor,hash_function_type>::
|
|
feat_to_image_space (
|
|
const rectangle& rect
|
|
) const
|
|
{
|
|
return fe.feat_to_image_space(rect);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
}
|
|
|
|
#endif // DLIB_HASHED_IMAGE_FEATUrES_Hh_
|
|
|
|
|