This is a part of the code in my project "human detection from picture"
File "integral_histogram.h"
View Code
1 // 2 // Author: Zhangpeng Tang 3 // Version: 0.1 4 // Date: 2012.03.10 5 // Description: This file is used to compute integral histogram. 6 // 7 // Copyright(C) 2012 Zhangpeng Tang 8 // All rights reserved. 9 //10 //11 12 13 #ifndef INTIGRAL_HISTOGRAM_H14 #define INTIGRAL_HISTOGRAM_H15 16 #include "image.h"17 18 #include19 #include 20 #include 21 #include 22 23 class IntegralHistogram24 {25 public:26 enum hist_type{undirected = 0, directed = 1};27 struct Param28 {29 hist_type htype;30 int dirnum;31 float exp; //weight factor, default 1;32 float sigma;33 Param(hist_type h = directed, int d = 8, float e = 1, float s = 0):htype(h),dirnum(d),exp(e),sigma(s){}34 };35 36 IntegralHistogram(hist_type htype = directed, int dirnum = 8, float exp = 1, float sigma = 0);37 IntegralHistogram(Param ¶m);38 ~IntegralHistogram();39 void build(Image &img); //img will be modified40 41 template 42 inline void get_hist(OutputIterator hist_begin, InputIterator bbox_begin, InputIterator bbox_endi, bool normalize = true) const;43 inline const float *get_inthist(int x, int y){ return _inthist + (y*_width + x)*_param.dirnum; }44 inline int dirnum() const { return _param.dirnum; }45 inline int width() const { return _width; }46 inline int height() const { return _height; }47 IntegralHistogram &load( const char *fn );48 IntegralHistogram &save( const char *fn );49 50 private:51 float *_inthist;52 int _height;53 int _width;54 static const float eps = 1e-10;55 Param _param;56 };57 58 template 59 inline void IntegralHistogram::get_hist(OutputIterator hist_begin, InputIterator bbox_begin, InputIterator bbox_end, bool normalize) const60 {61 typedef typename boost::detail::iterator_traits ::reference reference;62 while( bbox_begin != bbox_end )63 {64 reference x0 = *bbox_begin++;65 reference y0 = *bbox_begin++;66 reference x1 = *bbox_begin++;67 reference y1 = *bbox_begin++;68 69 if ( x0 < 0 || y0 < 0 || x0 > x1 || y0 > y1 || x1 >= _width || y1 >= _height)70 throw std::runtime_error( boost::str(boost::format("Invalid index [%1% %2% %3% %4%]") % x0 % y0 % x1 % y1) );71 72 float sum = 0;73 OutputIterator hist = hist_begin;74 for (int i = 0; i < _param.dirnum; ++i, ++hist_begin)75 {76 *hist_begin = _inthist[(y1*_width + x1)*_param.dirnum + i];77 if( x0 > 0 )78 *hist_begin -= _inthist[(y1*_width + x0 - 1)*_param.dirnum + i];79 if( y0 > 0 )80 *hist_begin -= _inthist[( (y0-1)*_width + x1 )*_param.dirnum + i];81 if( x0 >0 && y0 >0 )82 *hist_begin += _inthist[( (y0-1)*_width + x0 - 1 )*_param.dirnum + i];83 84 if( normalize )85 sum += *hist_begin;86 }87 if (normalize)88 {89 for (int i = 0; i < _param.dirnum; ++i, ++hist) { *hist /= (sum + eps); }90 }91 }92 }93 #endif //INTIGRAL_HISTOGRAM_H
File "integral_histogram.cpp"
View Code
1 // 2 // Author: Zhangpeng Tang 3 // Version: 0.1 4 // Date: 2012.03.10 5 // Description: This file is used to compute integral histogram. 6 // 7 // Copyright(C) 2012 Zhangpeng Tang 8 // All rights reserved. 9 // 10 // 11 12 13 #include "integral_histogram.h" 14 #include "image.h" 15 16 IntegralHistogram::IntegralHistogram(hist_type htype, int dirnum, float exp, float sigma) 17 { 18 _param.htype = htype; 19 _param.dirnum = dirnum; 20 _param.exp = exp; 21 _param.sigma = sigma; 22 23 _inthist = NULL; 24 } 25 26 IntegralHistogram::IntegralHistogram(Param ¶m): _param(param) 27 { 28 _inthist = NULL; 29 } 30 31 IntegralHistogram::~IntegralHistogram() 32 { 33 delete[] _inthist; 34 _inthist = NULL; 35 } 36 37 //calculate integral histogram for img, img will be modified 38 void IntegralHistogram::build( Image & img ) 39 { 40 const float PI = std::atan2(0, -1); 41 _width = static_cast (img.dimx()); 42 _height = static_cast (img.dimy()); 43 _inthist = new float[_width*_height*_param.dirnum]; 44 img.blur( _param.sigma ); 45 46 //[-1 0 1], [-1 0 1]'; 47 Image hmask(3, 1), vmask(1, 3); 48 hmask(0, 0) = vmask(0, 0) = -1; 49 hmask(1, 0) = vmask(0, 1) = 0; 50 hmask(2, 0) = vmask(0, 2) = 1; 51 52 Image vmasked = img.get_convolve( vmask ); 53 Image &hmasked = img.convolve( hmask ); 54 55 Image angle(_width, _height); 56 if (_param.htype == directed) 57 for (int i = 0; i < _width*_height; ++i) angle[i] = std::atan2(vmasked[i], hmasked[i]) + PI; 58 else //undirected 59 for (int i = 0; i < _width*_height; ++i) {angle[i] = std::atan(vmasked[i] / (hmasked[i] + eps)) + PI/2;} 60 61 hmasked.mul(hmasked) += vmasked.get_mul(vmasked); 62 Image &mod = hmasked; 63 if( (_param.exp - 1) < eps ) 64 mod.sqrt(); 65 else if( (_param.exp - 2) < eps ) 66 while(0); 67 else 68 mod.pow( _param.exp/2 ); 69 70 float theta = PI / _param.dirnum; 71 if (_param.htype == directed) theta *= 2; 72 73 for (int i = 0; i < _width*_height; ++i) 74 { 75 float *hist = _inthist + i*_param.dirnum; 76 for (int idir = 0; idir < _param.dirnum; ++idir) hist[idir] = 0; 77 78 int ileft = static_cast ( angle[i] / theta ); 79 int iright = ileft + 1; 80 81 float a = angle[i] - ileft*theta; 82 float b = iright*theta - angle[i]; 83 84 hist[ileft % _param.dirnum] = b*b*mod[i] / (a*a + b*b); 85 hist[iright % _param.dirnum] = a*a*mod[i] / (a*a + b*b); 86 } 87 88 for (int j = 1; j < _width; ++j) //1st row 89 { 90 float *hist = _inthist + j*_param.dirnum; 91 for (int idir = 0; idir < _param.dirnum; ++idir) 92 { 93 hist[idir] += hist[idir - 1]; 94 } 95 } 96 97 float *current_row_inthist = new float[_param.dirnum]; 98 for (int i = 1; i < _height; ++i) 99 {100 for (int idir = 0; idir < _param.dirnum; ++idir) current_row_inthist[idir] = 0;101 for (int j = 0; j < _width; ++j)102 {103 float *hist = _inthist + (i*_width + j)*_param.dirnum;104 for (int idir = 0; idir < _param.dirnum; ++idir) 105 {106 current_row_inthist[idir] += hist[idir];107 hist[idir] = _inthist[((i - 1)*_width + j)*_param.dirnum + idir] + current_row_inthist[idir]; 108 }109 }110 }111 }112 113 //load saved integral histogram from file system114 IntegralHistogram &IntegralHistogram::load( const char *fn )115 {116 std::fstream fin;117 fin.open( fn, std::ios::in|std::ios::binary);118 if (fin.good())119 {120 fin.read(reinterpret_cast(&_width), sizeof(_width)) \121 .read(reinterpret_cast (&_height), sizeof(_height)) \122 .read(reinterpret_cast (&_param.htype), sizeof(_param.htype)) \123 .read(reinterpret_cast (&_param.dirnum), sizeof(_param.dirnum)) \124 .read(reinterpret_cast (_inthist), _width*_height*_param.dirnum*sizeof(_inthist[0]));125 }126 else127 throw std::runtime_error( boost::str(boost::format("Failed to open %1%") % fn ) );128 fin.close();129 130 return *this;131 }132 133 //save integral histogram to file system134 IntegralHistogram &IntegralHistogram::save( const char *fn )135 {136 std::fstream fout;137 fout.open( fn, std::ios::out|std::ios::binary);138 if (fout.good())139 {140 fout.write(reinterpret_cast (&_width), sizeof(_width)) \141 .write(reinterpret_cast (&_height), sizeof(_height)) \142 .write(reinterpret_cast (&_param.htype), sizeof(_param.htype)) \143 .write(reinterpret_cast (&_param.dirnum), sizeof(_param.dirnum)) \144 .write(reinterpret_cast (_inthist), _width*_height*_param.dirnum*sizeof(_inthist[0]));145 }146 else147 throw std::runtime_error( boost::str(boost::format("Failed to open %1%") % fn ) );148 fout.close();149 150 return *this;151 }