mirror of https://github.com/davisking/dlib.git
Added an option to weight the features from a hashed_feature_image
relative to the number of times they occur in an image. I also set the new default behavior to use this relative weighting and changed the serialization format to accommodate this.
This commit is contained in:
parent
712c65779c
commit
615b3cf6a0
|
@ -68,6 +68,15 @@ namespace dlib
|
|||
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
|
||||
|
@ -111,6 +120,8 @@ namespace dlib
|
|||
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
|
||||
|
@ -127,9 +138,13 @@ namespace dlib
|
|||
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>
|
||||
|
@ -138,9 +153,16 @@ namespace dlib
|
|||
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);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -157,6 +179,7 @@ namespace dlib
|
|||
hashed_feature_image (
|
||||
)
|
||||
{
|
||||
clear();
|
||||
hash_feats.resize(1);
|
||||
}
|
||||
|
||||
|
@ -173,6 +196,8 @@ namespace dlib
|
|||
fe.clear();
|
||||
phash = hash_function_type();
|
||||
feats.clear();
|
||||
feat_counts.clear();
|
||||
uniform_feature_weights = false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -229,6 +254,7 @@ namespace dlib
|
|||
{
|
||||
fe.copy_configuration(item.fe);
|
||||
phash = item.phash;
|
||||
uniform_feature_weights = item.uniform_feature_weights;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -250,11 +276,26 @@ namespace dlib
|
|||
if (fe.size() != 0)
|
||||
{
|
||||
feats.set_size(fe.nr(), fe.nc());
|
||||
for (long r = 0; r < feats.nr(); ++r)
|
||||
feat_counts.assign(phash.num_hash_bins(),1);
|
||||
if (uniform_feature_weights)
|
||||
{
|
||||
for (long c = 0; c < feats.nc(); ++c)
|
||||
for (long r = 0; r < feats.nr(); ++r)
|
||||
{
|
||||
feats[r][c] = phash(fe(r,c));
|
||||
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]]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -263,6 +304,18 @@ namespace dlib
|
|||
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 = img.size()/(500.0*400.0);
|
||||
for (unsigned long i = 0; i < feat_counts.size(); ++i)
|
||||
{
|
||||
feat_counts[i] = scale/feat_counts[i];
|
||||
}
|
||||
}
|
||||
|
||||
fe.unload();
|
||||
}
|
||||
|
||||
|
@ -318,6 +371,45 @@ namespace dlib
|
|||
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 <
|
||||
|
@ -342,7 +434,7 @@ namespace dlib
|
|||
<< "\n\t this: " << this
|
||||
);
|
||||
|
||||
hash_feats[0] = std::make_pair(feats[row][col],1);
|
||||
hash_feats[0] = std::make_pair(feats[row][col],feat_counts[feats[row][col]]);
|
||||
return hash_feats;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,14 +28,15 @@ namespace dlib
|
|||
|
||||
INITIAL VALUE
|
||||
- size() == 0
|
||||
- uses_uniform_feature_weights() == false
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object is a tool for performing image feature extraction. In
|
||||
particular, it wraps another image feature extractor and converts
|
||||
the wrapped image feature vectors into sparse indicator vectors. It does
|
||||
this by hashing each feature vector into the range [0, get_num_dimensions()-1]
|
||||
and then returns a new vector which is zero everywhere except for
|
||||
the position determined by the hash.
|
||||
particular, it wraps another image feature extractor and converts the
|
||||
wrapped image feature vectors into sparse indicator vectors. It does this
|
||||
by hashing each feature vector into the range [0, get_num_dimensions()-1]
|
||||
and then returns a new vector which is zero everywhere except for the
|
||||
position determined by the hash.
|
||||
|
||||
|
||||
THREAD SAFETY
|
||||
|
@ -153,6 +154,30 @@ namespace dlib
|
|||
In this case, this is the number of hash bins. That is, get_hash().num_hash_bins()
|
||||
!*/
|
||||
|
||||
void use_relative_feature_weights (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #uses_uniform_feature_weights() == false
|
||||
!*/
|
||||
|
||||
void use_uniform_feature_weights (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #uses_uniform_feature_weights() == true
|
||||
!*/
|
||||
|
||||
bool uses_uniform_feature_weights (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns true if this object weights each feature with a value of 1 and
|
||||
false if it uses a weighting of 1/N where N is the number of occurrences
|
||||
of the feature in an image (note that we normalize N so that it is
|
||||
invariant to the size of the image given to load()).
|
||||
!*/
|
||||
|
||||
const descriptor_type& operator() (
|
||||
long row,
|
||||
long col
|
||||
|
@ -169,7 +194,13 @@ namespace dlib
|
|||
- To be precise, this function returns a sparse vector V such that:
|
||||
- V.size() == 1
|
||||
- V[0].first == get_hash()(BASE_FE(row,col))
|
||||
- V[0].second == 1
|
||||
- if (uses_uniform_feature_weights()) then
|
||||
- V[0].second == 1
|
||||
- else
|
||||
- V[0].second == 1/N where N is the number of times a feature in
|
||||
hash bin V[0].first was observed in the image given to load().
|
||||
Note that we scale all the counts so that they are invariant to
|
||||
the size of the image.
|
||||
!*/
|
||||
|
||||
const rectangle get_block_rect (
|
||||
|
|
Loading…
Reference in New Issue