www.pudn.com > colortracker.rar > histogram3d.h
#ifndef __HISTOGRAM_3d__ #define __HISTOGRAM_3d__ #include "preprocessor.h" #include "common.h" #includeusing std::ofstream; using std::ifstream; ////////////////////////////////////// typedef struct tagHISTBIN { int b1; int b2; int b3; tagHISTBIN() { b1 = 0; b2 = 0; b3 = 0; } inline tagHISTBIN(int _b1, int _b2, int _b3) { set_bin(_b1, _b2, _b3); } inline void set_bin (int _b1, int _b2, int _b3) { b1 = _b1; b2 = _b2; b3 = _b3; } } HISTBIN; ////////////////////////////////////// template class histogram3d { private: double m_hist[BINSIZE][BINSIZE][BINSIZE]; int m_totalMemSize; int m_numBins; int m_numColors; inline double & get_prob(HISTBIN & bin) { return((*this)[bin]); } inline void rgb2bin(const RGBTRIPLE & rgb, HISTBIN & bin) { const double alpha = 0.0; // -0.5 left edge of distribution const double binwidth = static_cast (m_numColors)/static_cast (BINSIZE); int r = floor( static_cast (rgb.rgbtRed-alpha)/binwidth ); int g = floor( static_cast (rgb.rgbtGreen-alpha)/binwidth ); int b = floor( static_cast (rgb.rgbtBlue-alpha)/binwidth ); bin.set_bin(r, g, b); } inline void bin2rgb(const HISTBIN & bin, RGBTRIPLE & rgb) { const double alpha = 0.0; // -0.5 left edge of distribution const double binwidth = static_cast (m_numColors)/static_cast (BINSIZE); rgb.rgbtRed = (bin.b1 - alpha)*binwidth + alpha; rgb.rgbtGreen = (bin.b2 - alpha)*binwidth + alpha; rgb.rgbtBlue = (bin.b2 - alpha)*binwidth + alpha; } inline void addtobin(HISTBIN & bin, double value = 1.0) { (*this)[bin] += value; } public: histogram3d() { m_numBins = BINSIZE*BINSIZE*BINSIZE; m_totalMemSize = m_numBins * sizeof(double); m_numColors = 256; clear(); } inline double *begin () { return (&(m_hist[0][0][0])); } inline const double *end () { return(&(m_hist[BINSIZE-1][BINSIZE-1][BINSIZE-1])+1); } inline double & operator[] (HISTBIN & bin) { return(m_hist[bin.b1][bin.b2][bin.b3]); } inline void addtobin(const RGBTRIPLE & rgb, const double value = 1.0) { HISTBIN bin; rgb2bin(rgb, bin); addtobin(bin, value); } inline double & get_prob(const RGBTRIPLE & rgb) { HISTBIN bin; rgb2bin(rgb, bin); return(get_prob(bin)); } void clear () { memset(m_hist, 0, m_totalMemSize); } histogram3d & copy(histogram3d & hist) { memcpy(hist.m_hist, m_hist, m_totalMemSize); return(hist); } void normalize() { double s = sum(); for (double *it = begin(); it != end(); it++) { if (*it) *it /= s; } } double sum() { double s = 0.0; for (double *it = begin(); it != end(); it++) s += *it; return (s); } void add_uniform (double weight = 1.0) { const double uniform = weight*(1.0/static_cast (m_numBins)); for (double *it = begin(); it != end(); it++) *it = uniform + *it*(1-weight); } void weighted_add (histogram3d & hist, const double & weight) { for (double *toptr = begin(), *fromptr = hist.begin(); toptr != end(); toptr++, fromptr++) *toptr = *toptr*weight + *fromptr*(1-weight); } void print_values (ofstream &os) { for (double *it = begin(); it != end(); it++) os << *it << endl; } void load_from_file (ifstream &is) { clear(); for (double *it = begin(); it != end(); it++) is >> *it; } void save_to_file (ofstream &os) { print_values (os); } }; ////////////////////////////////////// #endif __HISTOGRAM_3d__