Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

Histogram.cpp

Go to the documentation of this file.
00001 /**************************************************************************
00008  *
00009  * Source code for Real Time Image Library (libRTImage)
00010  *
00011  * Leeds Vision Group give permission for this code to be copied, modified
00012  * and distributed within the University of Leeds subject to the following
00013  * conditions:-
00014  *
00015  * - The code is not to be used for commercial gain.
00016  * - The code and use thereof will be attributed to the author where
00017  *   appropriate (inluding demonstrations which rely on it's use).
00018  * - All modified, distributions of the source files will retain this header.
00019  *
00020  ****************************************************************************/
00021 
00022 #include <cstdio>
00023 #include <cmath>
00024 #include <iostream>
00025 #include <fstream>
00026 
00027 using namespace std; 
00028 
00029 #include "Histogram.h"
00030 
00031 Histogram::Histogram(float        minimum_data_value,
00032                      float        maximum_data_value,
00033                      unsigned int bands_per_dimension,
00034                      unsigned int dimensionality)
00043  : min_val       (minimum_data_value),
00044    max_val       (maximum_data_value),
00045    bands_per_dim (bands_per_dimension),
00046    dim           (dimensionality),
00047    max_prob      (0),
00048    max_freq      (0)
00049 {
00050     band_size = (maximum_data_value - minimum_data_value) / bands_per_dim;
00051 
00052     no_bins = (unsigned int)pow((double)bands_per_dimension, (double)dim);
00053        
00054     frequency_data = new unsigned int[no_bins];   
00055     probs          = new float[no_bins];   
00056 
00057     reset_histogram() ;
00058 }
00059 
00060 
00061 Histogram::Histogram(char const* histfile)
00062  : frequency_data(0), probs(0)
00067 {
00068     load_histogram(histfile);
00069 }
00070 
00071 
00072 void Histogram::reset_histogram()
00078 {  
00079     unsigned int cnt;
00080 
00081     no_data_items = 0;
00082     for (cnt = 0; cnt < no_bins; cnt++) {
00083         frequency_data[cnt] = 0;
00084     }
00085     max_prob = 0;
00086     max_freq = 0;
00087 }
00088 
00089 
00090 void Histogram::add_new_data_item(int *data) 
00096 {
00097     unsigned int   increment;
00098     unsigned int   d_cnt;
00099     unsigned int   b_cnt;
00100     register float band_min;
00101     register float band_max;
00102     unsigned int   bin_no = 0; 
00103     register float d_val;
00104 
00105     increment = 1; 
00106 
00107     for (d_cnt = 0; d_cnt < dim; d_cnt++) {
00108     // Loop through dimensions
00109          band_min = min_val;
00110          band_max = min_val + band_size;
00111          d_val = (float)(data[d_cnt]);
00112          
00113          for (b_cnt = 0; b_cnt < bands_per_dim; b_cnt++) {
00114          // Loop through bands for this dimension
00115              if (d_val >= band_min && d_val <= band_max) break;
00116 
00117              band_min += band_size;
00118              band_max += band_size;
00119          }
00120          // Update bin no. w.r.t this dimension
00121          bin_no += b_cnt * increment;
00122 
00123          // Decrease size of increment
00124          increment *= bands_per_dim;
00125     }
00126 
00127     // Update frequency data
00128     frequency_data[bin_no]++;
00129     no_data_items++;
00130     
00131     if (frequency_data[bin_no] > max_freq) max_freq = frequency_data[bin_no];
00132 } 
00133 
00134 
00135 
00136 
00137 void Histogram::add_new_data_item(float *data) 
00143 {
00144     unsigned int increment;
00145     unsigned int d_cnt;
00146     unsigned int b_cnt;
00147     float        band_min;
00148     float        band_max;
00149     unsigned int bin_no = 0; 
00150 
00151     increment = 1; 
00152 
00153     for (d_cnt = 0; d_cnt < dim; d_cnt++) {
00154     // Loop through dimensions
00155          band_min = min_val;
00156          band_max = min_val + band_size;
00157          for (b_cnt = 0; b_cnt < bands_per_dim; b_cnt++){
00158          // Loop through bands for this dimension
00159              if (data[d_cnt] >= band_min && data[d_cnt] <= band_max) break;
00160 
00161              band_min += band_size;
00162              band_max += band_size;
00163          }
00164          // Update bin no. w.r.t this dimension
00165          bin_no += b_cnt * increment;
00166 
00167          // Decrease size of increment
00168          increment *= bands_per_dim;
00169     }
00170 
00171     // Update frequency data
00172     frequency_data[bin_no]++;
00173     no_data_items++;
00174     
00175     if (frequency_data[bin_no] > max_freq) max_freq = frequency_data[bin_no];
00176 } 
00177 
00178 void Histogram::calculate_probabilities()
00182 {
00183     unsigned int *f_ptr = frequency_data; 
00184     float        *p_ptr = probs;
00185     unsigned int cnt ;
00186 
00187     if(no_data_items > 0){
00188         max_prob = 0 ;
00189         for (cnt = 0; cnt < no_bins; cnt++, f_ptr++, p_ptr++){
00190         // Loop through all bins
00191             *p_ptr = (float)(*f_ptr) / (float)no_data_items;
00192             if (*p_ptr > max_prob) max_prob = *p_ptr;
00193         }
00194     }
00195     else{
00196         for (cnt = 0; cnt < no_bins; cnt++){
00197         // Loop through all bins
00198             *p_ptr = 0;
00199         }
00200         max_prob = 0;
00201     }
00202 
00203 }
00204 
00205 float Histogram::calculate_proportion_threshold(float proportion)
00213 {
00214     float        *p_ptr ;
00215     unsigned int cnt ;
00216     float        min_p = 0 ;
00217     float        new_min_p ;
00218     float        p_above_thresh = 1.0 ;
00219     unsigned int no_with_p ;
00220 
00221     while(p_above_thresh > proportion){
00222         new_min_p = 1.0 ;
00223         no_with_p = 0 ;
00224         for (cnt = 0, p_ptr = probs ; cnt < no_bins; cnt++, p_ptr++){
00225         // Loop through all bins
00226             if(*p_ptr > min_p && 
00227                *p_ptr < new_min_p){
00228             // Lowest this round
00229                 new_min_p = *p_ptr ;
00230                 no_with_p = 1 ;
00231             }
00232             else if(*p_ptr > min_p && 
00233                     *p_ptr == new_min_p){
00234             // Joint lowest
00235                 no_with_p++ ;
00236             }
00237         }
00238         p_above_thresh -= new_min_p * no_with_p ;
00239         if(p_above_thresh == 1.0){
00240         // Error, everything is 0
00241             break ;
00242         }
00243         min_p = new_min_p ;
00244     }
00245 
00246     return min_p ;
00247 }
00248 
00249 void Histogram::calculate_histogram()
00255 {
00256     unsigned int *f_ptr = frequency_data;
00257     float        *p_ptr = probs;
00258 
00259     max_prob = 0 ;
00260     for (unsigned int cnt = 0; cnt < no_bins; cnt++, f_ptr++, p_ptr++){
00261     // Loop through all bins
00262         *p_ptr = (float)(*f_ptr) / (float)max_freq;
00263         if (*p_ptr > max_prob) max_prob = *p_ptr;
00264     }
00265 }
00266 
00267 
00268 float Histogram::get_histogram_value(unsigned int *bin)
00276 {
00277     unsigned int bin_no = 0;
00278     unsigned int increment;
00279 
00280     increment = 1;
00281 
00282     for (unsigned int d_cnt = 0; d_cnt < dim; d_cnt++) {
00283     // Loop through dimensions
00284 
00285          bin_no += bin[d_cnt] * increment;
00286          increment *= bands_per_dim;
00287     }
00288 
00289     return probs[bin_no];
00290 }
00291 
00292 
00293 float Histogram::get_mapped_value(unsigned int *data)
00297 {
00298 #if 0
00299     for (unsigned int d_cnt = 0; d_cnt < dim; d_cnt++)
00300         data[d_cnt] /= (int) band_size;
00301     
00302     return get_histogram_value(data);
00303 #else
00304     unsigned int   increment;
00305     unsigned int   d_cnt;
00306     unsigned int   b_cnt;
00307     register float band_min;
00308     register float band_max;
00309     unsigned int   bin_no = 0; 
00310     register float d_val;
00311 
00312     increment = 1; 
00313 
00314     for (d_cnt = 0; d_cnt < dim; d_cnt++) {
00315     // Loop through dimensions
00316          band_min = min_val;
00317          band_max = min_val + band_size;
00318          d_val = (float)(data[d_cnt]);
00319          
00320          for (b_cnt = 0; b_cnt < bands_per_dim; b_cnt++) {
00321          // Loop through bands for this dimension
00322              if (d_val >= band_min && d_val <= band_max) break;
00323 
00324              band_min += band_size;
00325              band_max += band_size;
00326          }
00327          // Update bin no. w.r.t this dimension
00328          bin_no += b_cnt * increment;
00329 
00330          // Decrease size of increment
00331          increment *= bands_per_dim;
00332     }
00333     
00334     return probs[bin_no];
00335 #endif
00336 }
00337 
00338 
00339 float Histogram::calculate_difference(Histogram *hist)
00346 {
00347     unsigned int b_cnt;
00348     float        diff;
00349     float        ret_val = 0;
00350     float        *t_ptr;
00351     float        *h_ptr;
00352 
00353     t_ptr = probs;
00354     h_ptr = hist->probs;
00355     for (b_cnt = 0; b_cnt < no_bins; b_cnt++) {
00356         diff = *t_ptr - *h_ptr;
00357         if (diff < 0) diff = -diff;
00358         ret_val += diff;
00359 
00360         t_ptr++;
00361         h_ptr++;
00362     }
00363 
00364     return ret_val;
00365 }
00366 
00367 
00368 void Histogram::save_histogram(char const* histfile)
00372 {
00373     FILE* fd = fopen(histfile, "w");
00374 
00375     fprintf(fd, "<?xml version=\"1.0\" ?>\n\n");
00376     
00377     fprintf(fd, "<histogram min-value=\"%f\" max-value=\"%f\" " 
00378                 "bands=\"%u\" dimensionality=\"%u\">\n",
00379                 min_val, max_val, bands_per_dim, dim);
00380 
00381     for (unsigned int b_cnt = 0; b_cnt < no_bins; b_cnt++) {
00382         float p = probs[b_cnt];
00383         if (p) fprintf(fd, "  <prob index=\"%u\">%f</prob>\n", b_cnt, p);
00384     }
00385     
00386     fprintf(fd, "</histogram>\n");
00387     fclose(fd);
00388 }
00389 
00390 
00391 void Histogram::load_histogram(char const* histfile)
00395 {
00396     delete [] frequency_data;
00397     delete [] probs;
00398     
00399     FILE* fd = fopen(histfile, "r");
00400     if (fd == 0) throw "Could not open hst file.";
00401 
00402     int n;  // return values for fscanf, set to number of items read
00403 
00404     /* xml version string */
00405     
00406     float xmlversion = 0;
00407    
00408     n = fscanf(fd, "<?xml version=\"%f\" ?>\n\n", &xmlversion);
00409     
00410     if (xmlversion == 0) throw "Incompatible hst file format";
00411 
00412 
00413     /* histogram attributes */
00414     
00415     n = fscanf(fd, "<histogram min-value=\"%f\" max-value=\"%f\" "
00416                               "bands=\"%u\" dimensionality=\"%u\">\n",
00417                &min_val, &max_val, &bands_per_dim, &dim);
00418     
00419     if (n != 4) throw "error in hst file, unable to import data.";
00420 
00421     band_size = (max_val - min_val) / bands_per_dim;
00422     no_bins   = (unsigned int) pow((double)bands_per_dim, (double)dim);
00423    
00424     frequency_data = new unsigned int[no_bins];   
00425     probs          = new float[no_bins];   
00426    
00427     for (unsigned int cnt = 0; cnt < no_bins; cnt++) {
00428         frequency_data[cnt] = 0;
00429         probs[cnt]          = 0.0;
00430     }
00431 
00432     
00433     /* probabilities */
00434     
00435     unsigned int bin, i = 0;
00436     float p = 0;    // probability
00437     
00438     n = fscanf(fd, "  <prob index=\"%u\">%f</prob>\n", &bin, &p);
00439     max_prob = p;
00440     while (n == 2) {
00441         probs[bin] = p;
00442         n = fscanf(fd, "  <prob index=\"%u\">%f</prob>\n", &bin, &p);
00443         if (p > max_prob) max_prob = p;
00444         i++;
00445     };
00446     
00447     /* end of file */
00448     
00449     char last[2];
00450     n = fscanf(fd, "/histogram%[>]", last);
00451     if (n != 1)
00452         throw "Reading hst file.";
00453     
00454     fclose(fd);
00455 }
00456 
00457 void Histogram::get_best_bin(unsigned int *bin)
00461 {
00462     unsigned int best_bin = 0 ; 
00463     unsigned int b_cnt ; 
00464     unsigned int increment = 1 ; 
00465     int          d_cnt ; 
00466     float        highest_p = -1 ;
00467 
00468     for (b_cnt = 0; b_cnt < no_bins; b_cnt++) {
00469     // Loop through bins
00470         if(probs[b_cnt] > highest_p){
00471             highest_p = probs[b_cnt] ;
00472             best_bin = b_cnt ;
00473         }
00474     }
00475 
00476     for(d_cnt = dim-1 ; d_cnt> 0 ; d_cnt--){
00477         increment *= bands_per_dim; 
00478     }
00479 
00480     for(d_cnt = dim-1 ; d_cnt>= 0 ; d_cnt--){
00481         bin[d_cnt] = 0 ;
00482         while(best_bin >= increment){
00483             bin[d_cnt] ++ ;
00484             best_bin -= increment ;
00485         }
00486         increment /= bands_per_dim ;
00487     }
00488 }

Generated at Fri Aug 13 17:29:20 2004 for libRTImage by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001