// Copyright (C) 2011 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_NEAREST_NEIGHBOR_FeATURE_IMAGE_Hh_ #define DLIB_NEAREST_NEIGHBOR_FeATURE_IMAGE_Hh_ #include "nearest_neighbor_feature_image_abstract.h" #include <vector> #include "../algs.h" #include "../matrix.h" #include "../statistics.h" namespace dlib { // ---------------------------------------------------------------------------------------- template < typename feature_extractor > class nearest_neighbor_feature_image : noncopyable { /*! INITIAL VALUE - nn_feats.size() == 1 CONVENTION - nn_feats.size() == 1 !*/ public: typedef std::vector<std::pair<unsigned int,double> > descriptor_type; nearest_neighbor_feature_image ( ); void clear ( ); void copy_configuration ( const feature_extractor& item ); void copy_configuration ( const nearest_neighbor_feature_image& item ); template < typename image_type > inline void load ( const image_type& img ); inline unsigned long size ( ) const; inline long nr ( ) const; inline long nc ( ) const; inline long get_num_dimensions ( ) const; template <typename vector_type> void set_basis ( const vector_type& new_basis ); 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 nearest_neighbor_feature_image<T>& item, std::ostream& out ); template <typename T> friend void deserialize ( nearest_neighbor_feature_image<T>& item, std::istream& in ); private: array2d<unsigned long> feats; feature_extractor fe; std::vector<typename feature_extractor::descriptor_type> basis; // 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 nn_feats; }; // ---------------------------------------------------------------------------------------- template <typename T> void serialize ( const nearest_neighbor_feature_image<T>& item, std::ostream& out ) { serialize(item.feats, out); serialize(item.fe, out); serialize(item.basis, out); } template <typename T> void deserialize ( nearest_neighbor_feature_image<T>& item, std::istream& in ) { deserialize(item.feats, in); deserialize(item.fe, in); deserialize(item.basis, in); } // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // nearest_neighbor_feature_image member functions // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- template < typename feature_extractor > nearest_neighbor_feature_image<feature_extractor>:: nearest_neighbor_feature_image ( ) { nn_feats.resize(1); } // ---------------------------------------------------------------------------------------- template < typename feature_extractor > void nearest_neighbor_feature_image<feature_extractor>:: clear ( ) { feats.clear(); fe.clear(); basis.clear(); } // ---------------------------------------------------------------------------------------- template < typename feature_extractor > void nearest_neighbor_feature_image<feature_extractor>:: copy_configuration ( const feature_extractor& item ) { fe.copy_configuration(item); } // ---------------------------------------------------------------------------------------- template < typename feature_extractor > void nearest_neighbor_feature_image<feature_extractor>:: copy_configuration ( const nearest_neighbor_feature_image& item ) { fe.copy_configuration(item.fe); basis = item.basis; } // ---------------------------------------------------------------------------------------- template < typename feature_extractor > template < typename image_type > void nearest_neighbor_feature_image<feature_extractor>:: load ( const image_type& img ) { fe.load(img); feats.set_size(fe.nr(), fe.nc()); // find the nearest neighbor for each feature vector and store the // result in feats. for (long r = 0; r < feats.nr(); ++r) { for (long c = 0; c < feats.nc(); ++c) { const typename feature_extractor::descriptor_type& local_feat = fe(r,c); double best_dist = std::numeric_limits<double>::infinity(); unsigned long best_idx = 0; for (unsigned long i = 0; i < basis.size(); ++i) { double dist = length_squared(local_feat - basis[i]); if (dist < best_dist) { best_dist = dist; best_idx = i; } } feats[r][c] = best_idx; } } fe.unload(); } // ---------------------------------------------------------------------------------------- template < typename feature_extractor > unsigned long nearest_neighbor_feature_image<feature_extractor>:: size ( ) const { return feats.size(); } // ---------------------------------------------------------------------------------------- template < typename feature_extractor > long nearest_neighbor_feature_image<feature_extractor>:: nr ( ) const { return feats.nr(); } // ---------------------------------------------------------------------------------------- template < typename feature_extractor > long nearest_neighbor_feature_image<feature_extractor>:: nc ( ) const { return feats.nc(); } // ---------------------------------------------------------------------------------------- template < typename feature_extractor > long nearest_neighbor_feature_image<feature_extractor>:: get_num_dimensions ( ) const { return basis.size(); } // ---------------------------------------------------------------------------------------- template <typename feature_extractor> template <typename vector_type> void nearest_neighbor_feature_image<feature_extractor>:: set_basis ( const vector_type& new_basis ) { basis.assign(new_basis.begin(), new_basis.end()); } // ---------------------------------------------------------------------------------------- template < typename feature_extractor > const typename nearest_neighbor_feature_image<feature_extractor>::descriptor_type& nearest_neighbor_feature_image<feature_extractor>:: 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 nearest_neighbor_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 ); nn_feats[0] = std::make_pair(feats[row][col],1); return nn_feats; } // ---------------------------------------------------------------------------------------- template < typename feature_extractor > const rectangle nearest_neighbor_feature_image<feature_extractor>:: get_block_rect ( long row, long col ) const { return fe.get_block_rect(row,col); } // ---------------------------------------------------------------------------------------- template < typename feature_extractor > const point nearest_neighbor_feature_image<feature_extractor>:: image_to_feat_space ( const point& p ) const { return fe.image_to_feat_space(p); } // ---------------------------------------------------------------------------------------- template < typename feature_extractor > const rectangle nearest_neighbor_feature_image<feature_extractor>:: image_to_feat_space ( const rectangle& rect ) const { return fe.image_to_feat_space(rect); } // ---------------------------------------------------------------------------------------- template < typename feature_extractor > const point nearest_neighbor_feature_image<feature_extractor>:: feat_to_image_space ( const point& p ) const { return fe.feat_to_image_space(p); } // ---------------------------------------------------------------------------------------- template < typename feature_extractor > const rectangle nearest_neighbor_feature_image<feature_extractor>:: feat_to_image_space ( const rectangle& rect ) const { return fe.feat_to_image_space(rect); } // ---------------------------------------------------------------------------------------- } #endif // DLIB_NEAREST_NEIGHBOR_FeATURE_IMAGE_Hh_