VLFeat.org

API docs

  • Home
    • Download and Install
    • API docs
    • Matlab docs
    • About VLFeat
  • Tutorials
    • SIFT
    • MSER
    • IKM
    • HIKM
    • AIB
    • Utils
  • Main Page
  • Related Pages
  • Data Structures
  • Files
  • Examples

hikmeans.c

Go to the documentation of this file.
00001 
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <math.h>
00032 
00033 #include "hikmeans.h"
00034 
00049 vl_uint8*
00050 vl_hikm_copy_subset (vl_uint8 const * data, 
00051                      vl_uint * ids, 
00052                      int N, int M, 
00053                      vl_uint id, int *N2)
00054 {
00055   int i ;
00056   int count = 0;
00057 
00058   /* count how many data points with this label there are */
00059   for (i = 0 ; i < N ; i++)
00060     if (ids[i] == id)
00061       count ++ ;
00062   *N2 = count ;
00063   
00064   /* copy each datum to the buffer */
00065   {
00066     vl_uint8 * new_data = vl_malloc (sizeof(vl_uint8) * M * count);    
00067     count = 0;
00068     for (i = 0 ; i < N ; i ++)
00069       if (ids[i] == id)
00070         {
00071           memcpy(new_data + count * M, 
00072                  data     + i     * M, 
00073                  sizeof(vl_uint8) * M);
00074           count ++ ;
00075         }    
00076     *N2 = count ;
00077     return new_data ;
00078   }  
00079 }
00080 
00095 static VlHIKMNode * 
00096 xmeans (VlHIKMTree *tree, 
00097         vl_uint8 const *data, 
00098         int N, int K, int height)
00099 {
00100   VlHIKMNode *node = vl_malloc (sizeof(VlHIKMNode)) ;
00101   vl_uint     *ids = vl_malloc (sizeof(vl_uint) * N) ;
00102 
00103   node-> filter   = vl_ikm_new (tree -> method) ;    
00104   node-> children = (height == 1) ? 0 : vl_malloc (sizeof(VlHIKMNode*) * K) ;
00105 
00106   vl_ikm_set_max_niters (node->filter, tree->max_niters) ;
00107   vl_ikm_set_verbosity  (node->filter, tree->verb - 1  ) ;
00108   vl_ikm_init_rand_data (node->filter, data, tree->M, N, K) ;
00109   vl_ikm_train          (node->filter, data, N) ;
00110   vl_ikm_push           (node->filter, ids, data, N) ;
00111   
00112   /* recurse for each child */
00113   if (height > 1) {
00114     int k ;
00115     for (k = 0 ; k < K ; k ++) {
00116       int partition_N ;
00117       int partition_K ;
00118       vl_uint8 *partition ;
00119       
00120       partition = vl_hikm_copy_subset
00121         (data, ids, N, tree->M, k, &partition_N) ;
00122       
00123       partition_K = VL_MIN (K, partition_N) ;
00124       
00125       node->children [k] = xmeans
00126         (tree, partition, partition_N, partition_K, height - 1) ;
00127       
00128       vl_free (partition) ;
00129 
00130       if (tree->verb > tree->depth - height) {
00131         VL_PRINTF("hikmeans: branch at depth %d: %6.1f %% completed\n", 
00132                   tree->depth - height,
00133                   (double) (k+1) / K * 100) ;
00134       }
00135     }
00136   }
00137   
00138   vl_free (ids) ;
00139   return node ;
00140 }
00141 
00151 static void 
00152 xdelete (VlHIKMNode *node)
00153 {
00154   if(node) {
00155     int k ;
00156     if (node->children) {
00157       for(k = 0 ; k < vl_ikm_get_K (node->filter) ; ++k)
00158         xdelete (node->children[k]) ;
00159       vl_free (node->children) ;
00160     }
00161     if (node->filter) 
00162       vl_ikm_delete (node->filter) ;
00163     vl_free(node);
00164   }
00165 }
00166 
00173 VL_EXPORT
00174 VlHIKMTree *
00175 vl_hikm_new (int method)
00176 {
00177   VlHIKMTree *f = vl_malloc (sizeof(VlHIKMTree)) ;
00178   f -> M          = 0 ;
00179   f -> K          = 0 ;
00180   f -> max_niters = 200 ;
00181   f -> method     = method ;
00182   f -> verb       = 0 ;
00183   f -> depth      = 0 ;
00184   f -> root       = 0 ;
00185   return f ;
00186 }
00187 
00193 VL_EXPORT
00194 void
00195 vl_hikm_delete (VlHIKMTree *f)
00196 {
00197   if (f) {
00198     xdelete (f -> root) ;
00199     vl_free (f) ;
00200   }
00201 }
00202 
00216 VL_EXPORT
00217 void
00218 vl_hikm_init (VlHIKMTree *f, int M, int K, int depth)
00219 {
00220   assert(depth > 0) ;
00221   assert(M     > 0) ;
00222   assert(K     > 0) ;
00223   
00224   xdelete (f -> root) ;
00225   f -> root = 0;
00226   
00227   f -> M = M ;
00228   f -> K = K ;
00229   f -> depth = depth ;
00230 }
00231 
00239 VL_EXPORT
00240 void
00241 vl_hikm_train (VlHIKMTree *f, vl_uint8 const *data, int N)
00242 {
00243   f -> root  = xmeans (f, data, N, VL_MIN(f->K, N), f->depth) ;
00244 }
00245 
00260 VL_EXPORT
00261 void
00262 vl_hikm_push (VlHIKMTree *f, vl_uint *asgn, vl_uint8 const *data, int N)
00263 {
00264   int i, d,
00265     M = vl_hikm_get_ndims (f),
00266     depth = vl_hikm_get_depth (f) ;
00267   
00268   /* for each datum */
00269   for(i = 0 ; i < N ; i++) {
00270     VlHIKMNode *node = f->root ;
00271     d = 0 ;      
00272     while (node) {
00273       /*
00274       vl_uint best = 
00275         vl_ikm_push_one (vl_ikm_get_centers (node->filter),  
00276                          data + i * M,
00277                          M,
00278                          vl_ikm_get_K (node->filter)) ;
00279       */
00280       
00281       vl_uint best ;
00282       vl_ikm_push (node->filter, &best, data + i * M, 1) ;
00283       
00284       asgn [i*depth + d] = best ;
00285       ++ d ;
00286       
00287       if (!node->children) break ;
00288       node = node->children [best] ;
00289     }
00290   }
00291 }
Copyright © 2008 Andrea Vedaldi and Brian Fulkerson