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_H 14 #define INTIGRAL_HISTOGRAM_H 15 16 #include "image.h" 17 18 #include <boost/detail/iterator.hpp> 19 #include <boost/format.hpp> 20 #include <stdexcept> 21 #include <fstream> 22 23 class IntegralHistogram 24 { 25 public: 26 enum hist_type{undirected = 0, directed = 1}; 27 struct Param 28 { 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 modified 40 41 template<typename OutputIterator, typename InputIterator> 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<typename OutputIterator, typename InputIterator> 59 inline void IntegralHistogram::get_hist(OutputIterator hist_begin, InputIterator bbox_begin, InputIterator bbox_end, bool normalize) const 60 { 61 typedef typename boost::detail::iterator_traits<InputIterator>::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<int>(img.dimx()); 42 _height = static_cast<int>(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<int>( 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 system 114 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<char *>(&_width), sizeof(_width)) \ 121 .read(reinterpret_cast<char *>(&_height), sizeof(_height)) \ 122 .read(reinterpret_cast<char *>(&_param.htype), sizeof(_param.htype)) \ 123 .read(reinterpret_cast<char *>(&_param.dirnum), sizeof(_param.dirnum)) \ 124 .read(reinterpret_cast<char *>(_inthist), _width*_height*_param.dirnum*sizeof(_inthist[0])); 125 } 126 else 127 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 system 134 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<char *>(&_width), sizeof(_width)) \ 141 .write(reinterpret_cast<char *>(&_height), sizeof(_height)) \ 142 .write(reinterpret_cast<char *>(&_param.htype), sizeof(_param.htype)) \ 143 .write(reinterpret_cast<char *>(&_param.dirnum), sizeof(_param.dirnum)) \ 144 .write(reinterpret_cast<char *>(_inthist), _width*_height*_param.dirnum*sizeof(_inthist[0])); 145 } 146 else 147 throw std::runtime_error( boost::str(boost::format("Failed to open %1%") % fn ) ); 148 fout.close(); 149 150 return *this; 151 }