00001 #ifndef mbl_clusters_h_ 00002 #define mbl_clusters_h_ 00003 //: 00004 // \file 00005 // \brief Class to record clusters of data, for faster neighbour finding 00006 // \author Tim Cootes 00007 00008 #include <vcl_vector.h> 00009 #include <vcl_iostream.h> 00010 #include <vsl/vsl_fwd.h> 00011 00012 //: Class to record clusters of data, for faster neighbour finding 00013 // Used to record clusters of objects of type T. 00014 // D::d(T t1, T t2) is a measure of distance between two objects. 00015 // It must obey the triangle inequality: 00016 // D::d(t1,t2)<=D::d(t1,t3)+D::d(t2,t3). 00017 // 00018 // Pointer retained to an external vector of objects. The class 00019 // is designed to allow fast location of the nearest of the external 00020 // objects to a given new object. It represents the data as a 00021 // set of key point positions, together with a list of indices into 00022 // the external data for each cluster. 00023 // 00024 // Thus to find the nearest neighbour, we first check for proximity 00025 // to the keypoints, and only consider objects in the clusters 00026 // which are sufficiently close. 00027 template<class T, class D> 00028 class mbl_clusters 00029 { 00030 private: 00031 //: Pointer to external list of objects 00032 const vcl_vector<T>* data_; 00033 00034 //: Cluster key point 00035 vcl_vector<T> p_; 00036 00037 //: Maximum radius for any cluster 00038 double max_r_; 00039 00040 //: Indices of objects associated with each cluster 00041 vcl_vector<vcl_vector<unsigned> > index_; 00042 00043 //: Furthest distance of a cluster object from key point for cluster 00044 vcl_vector<double> r_; 00045 00046 public: 00047 mbl_clusters(); 00048 00049 //: Empty clusters 00050 void empty(); 00051 00052 //: Define maximum radius for each cluster 00053 void set_max_r(double r); 00054 00055 //: Define external data array (pointer retained) 00056 // Empty existing clusters, then process every element of data 00057 // to create clusters, by calling add_object() 00058 void set_data(const vcl_vector<T>& data); 00059 00060 //: Define external data array (pointer retained) 00061 // Use carefully! This sets the internal pointer to 00062 // point to data. Really only to be used after loading 00063 // internals using b_read(bfs). 00064 void set_data_ptr(const vcl_vector<T>& data); 00065 00066 //: External list of objects 00067 const vcl_vector<T>& data() const { return *data_; } 00068 00069 //: Maximum radius for any cluster 00070 double max_r() const { return max_r_; } 00071 00072 //: Cluster key points 00073 const vcl_vector<T>& p() const { return p_; } 00074 00075 //: Number of clusters 00076 unsigned n_clusters() const { return p_.size(); } 00077 00078 //: Furthest distance of a cluster object from key point for cluster 00079 const vcl_vector<double>& r() const { return r_; } 00080 00081 //: Indices of objects associated with each cluster 00082 const vcl_vector<vcl_vector<unsigned> >& index() const 00083 { return index_; } 00084 00085 //: Set given radius 00086 void set_r(unsigned i, double r) { r_[i]=r; } 00087 00088 //: Return index of nearest object in data() to t 00089 // Nearest object in data() to t is given by data()[nearest(t,d)]; 00090 // The distance to the point is d 00091 unsigned nearest(const T& t, double& d) const; 00092 00093 //: Return index of nearest object in data() to t 00094 // Consider only objects in clusters given in c_list 00095 // Nearest object in data() to t is given by data()[nearest(t,d)]; 00096 // The distance to the point is d 00097 unsigned nearest(const T& t, double& d, 00098 const vcl_vector<unsigned>& c_list) const; 00099 00100 //: Return index of nearest cluster in data() to t 00101 // Finds nearest cluster key point to t 00102 // The distance to the point is d 00103 unsigned nearest_cluster(const T& t, double& d) const; 00104 00105 //: Return indices of clusters which may contain nearest point to t 00106 // Searches through all the clusters, returning list in near_c 00107 void nearest_clusters(const T& t, double& max_d, 00108 vcl_vector<unsigned>& near_c) const; 00109 00110 //: Return indices of clusters which may contain nearest point to t 00111 // Searches through clusters listed in c_list. 00112 // On input, max_d gives initial limit on distance. 00113 // On exit, max_d gives the revised limit on the distance 00114 void nearest_clusters(const T& t, double& max_d, 00115 const vcl_vector<unsigned>& c_list, 00116 vcl_vector<unsigned>& near_c) const; 00117 00118 //: Append new object with index i and assign to a cluster 00119 // Assumes that new object data()[i] is available. 00120 // Deduce which cluster it belongs to and add it. 00121 // Create new cluster if further than max_r() from any. 00122 // r is the radius associated with data()[i], which is 00123 // zero for a single point, but non-zero when the point 00124 // is itself a key point for a cluster (eg in mbl_cluster_tree) 00125 // Return index of cluster it is assigned to 00126 unsigned add_object(unsigned i, double r=0.0); 00127 00128 //: Create a new cluster around point data()[i] 00129 // Assumes that new object data()[i] is available. 00130 // Return index of cluster 00131 unsigned create_cluster(unsigned i, double r=0.0); 00132 00133 //: Assign object data()[i] to cluster ci, knowing distance r. 00134 // r is the distance D::d(data()[i],p()[ci]) 00135 void assign_to_cluster(unsigned i, unsigned ci, double r); 00136 00137 //: Finds list of clusters whose keypoint is within d of t 00138 // Returns number of such clusters. If >0, then nearest_c 00139 // gives index of cluster with centre nearest to t 00140 unsigned clusters_within_d(const T& t, double d, 00141 vcl_vector<unsigned>& c_list, 00142 unsigned& nearest_c, 00143 double& min_d); 00144 00145 //: Finds list of clusters whose keypoint is within max_r of t 00146 // Returns number of such clusters. If >0, then nearest_c 00147 // gives index of cluster with centre nearest to t 00148 unsigned clusters_within_max_r(const T& t, 00149 vcl_vector<unsigned>& c_list, 00150 unsigned& nearest_c, 00151 double& min_d); 00152 00153 //: Finds list of clusters whose keypoint is within d of t 00154 // Only considers subset of clusters listed in in_list 00155 // Returns number of such clusters. If >0, then nearest_c 00156 // gives index of cluster with centre nearest to t 00157 unsigned clusters_within_d(const T& t, double d, 00158 const vcl_vector<unsigned>& in_list, 00159 vcl_vector<unsigned>& c_list, 00160 unsigned& nearest_c, 00161 double& min_d); 00162 00163 //: Finds list of clusters whose keypoint is within max_r of t 00164 // Only considers subset of clusters listed in index 00165 // Returns number of such clusters. If >0, then nearest_c 00166 // gives index of cluster with centre nearest to t 00167 unsigned clusters_within_max_r(const T& t, 00168 const vcl_vector<unsigned>& in_list, 00169 vcl_vector<unsigned>& c_list, 00170 unsigned& nearest_c, 00171 double& min_d); 00172 00173 //: Create list of object indices in listed clusters 00174 // Concatenates lists of indices for each cluster in c_list 00175 void in_clusters(const vcl_vector<unsigned>& c_list, 00176 vcl_vector<unsigned>& o_list) const; 00177 00178 //: Write out list of elements in each cluster 00179 void print_cluster_sets(vcl_ostream& os) const; 00180 00181 //: Version number for I/O 00182 short version_no() const; 00183 00184 //: Print class to os 00185 void print_summary(vcl_ostream& os) const; 00186 00187 //: Save class to binary file stream. 00188 // Warning: Does not save external data - that must 00189 // be recorded separately. 00190 void b_write(vsl_b_ostream& bfs) const; 00191 00192 //: Load class from binary file stream 00193 // Warning: Does not load or link external data - that must 00194 // be recorded separately, then connected using set_data_ptr() 00195 void b_read(vsl_b_istream& bfs); 00196 }; 00197 00198 //: Binary file stream output operator for class reference 00199 template<class T, class D> 00200 void vsl_b_write(vsl_b_ostream& bfs, const mbl_clusters<T,D>& c); 00201 00202 //: Binary file stream input operator for class reference 00203 template<class T, class D> 00204 void vsl_b_read(vsl_b_istream& bfs, mbl_clusters<T,D>& c); 00205 00206 //: Stream output operator for class reference 00207 template<class T, class D> 00208 vcl_ostream& operator<<(vcl_ostream& os,const mbl_clusters<T,D>& c); 00209 00210 #endif // mbl_clusters_h_