HaarFeature.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /**
  2. * @file HaarFeature.cpp
  3. * @brief simple haar like feature
  4. * @author Erik Rodner
  5. * @date 04/21/2008
  6. */
  7. #include <iostream>
  8. #include "vislearning/features/fpfeatures/HaarFeature.h"
  9. #include "vislearning/cbaselib/FeaturePool.h"
  10. using namespace OBJREC;
  11. using namespace std;
  12. using namespace NICE;
  13. void HaarFeature::explode( FeaturePool & featurePool, bool variableWindow ) const
  14. {
  15. HaarFeature *hf = new HaarFeature( *this );
  16. hf->pos1 = 0;
  17. hf->pos2 = 0;
  18. hf->type = HAARTYPE_HORIZONTAL;
  19. for ( hf->pos1 = 0 ; hf->pos1 < hf->window_size_y - 1 ; hf->pos1 += hf->step_y )
  20. featurePool.addFeature( hf->clone(), hf->step_y / ( double )( HAARTYPE_NUMTYPES * hf->window_size_y ) );
  21. hf->pos1 = 0;
  22. hf->pos2 = 0;
  23. hf->type = HAARTYPE_VERTICAL;
  24. for ( hf->pos1 = 0 ; hf->pos1 < hf->window_size_x - 1; hf->pos1 += hf->step_x )
  25. featurePool.addFeature( hf->clone(), hf->step_x / ( double )( HAARTYPE_NUMTYPES * hf->window_size_x ) );
  26. hf->type = HAARTYPE_DIAGONAL;
  27. hf->pos1 = 0;
  28. hf->pos2 = 0;
  29. for ( hf->pos1 = 0 ; hf->pos1 < hf->window_size_x - 1; hf->pos1 += hf->step_x )
  30. for ( hf->pos2 = 0 ; hf->pos2 < hf->window_size_y - 1 ; hf->pos2 += hf->step_y )
  31. featurePool.addFeature( hf->clone(),
  32. hf->step_x * hf->step_y / ( double )( HAARTYPE_NUMTYPES * hf->window_size_x * hf->window_size_y ) );
  33. hf->pos1 = 0;
  34. hf->pos2 = 0;
  35. hf->type = HAARTYPE_3BLOCKS;
  36. for ( hf->pos1 = 0 ; hf->pos1 < hf->window_size_x - 2*hf->step_x ; hf->pos1 += hf->step_x )
  37. for ( hf->pos2 = hf->pos1 + hf->step_x; hf->pos2 < hf->window_size_x - hf->step_x ; hf->pos2 += hf->step_x )
  38. featurePool.addFeature( hf->clone(),
  39. ( 2.0 * hf->step_x ) / ( HAARTYPE_NUMTYPES * ( hf->window_size_x - hf->step_x ) ) );
  40. delete hf;
  41. }
  42. Feature *HaarFeature::clone() const
  43. {
  44. HaarFeature *fp = new HaarFeature( *this );
  45. return fp;
  46. }
  47. /************* HaarFeature **************/
  48. HaarFeature::HaarFeature( const Config *conf )
  49. {
  50. window_size_x = conf->gI( "HaarFeature", "window_size_x", 24 );
  51. window_size_y = conf->gI( "HaarFeature", "window_size_y", 24 );
  52. step_x = conf->gI( "HaarFeature", "step_x", 1 );
  53. step_y = conf->gI( "HaarFeature", "step_y", 1 );
  54. }
  55. HaarFeature::HaarFeature( int _window_size_x,
  56. int _window_size_y,
  57. int _step_x,
  58. int _step_y )
  59. {
  60. window_size_x = _window_size_x;
  61. window_size_y = _window_size_y;
  62. pos1 = 1;
  63. pos2 = 0;
  64. step_x = _step_x;
  65. step_y = _step_y;
  66. type = HaarFeature::HAARTYPE_HORIZONTAL;
  67. }
  68. HaarFeature::~HaarFeature()
  69. {
  70. }
  71. double HaarFeature::val( const Example *example ) const
  72. {
  73. const NICE::MultiChannelImageT<long> & img = example->ce->getLChannel( CachedExample::L_INTEGRALIMAGE );
  74. const long *integralImage = img.data[0];
  75. int xsize = img.xsize;
  76. int ysize = img.ysize;
  77. int x = example->x;
  78. int y = example->y;
  79. long tl, tr, bl, br;
  80. int exwidth = example->width;
  81. if ( exwidth != 0 )
  82. {
  83. int exheight = example->height;
  84. tl = ( x - exwidth / 2 ) + ( y - exheight / 2 ) * xsize;
  85. tr = tl + exwidth - 1;
  86. bl = tl + ( exheight - 1 ) * xsize;
  87. br = bl + exwidth - 1;
  88. } else {
  89. tl = ( x - window_size_x / 2 ) + ( y - window_size_y / 2 ) * xsize;
  90. tr = tl + window_size_x - 1;
  91. bl = tl + ( window_size_y - 1 ) * xsize;
  92. br = bl + ( window_size_x - 1 );
  93. }
  94. assert( tl < xsize*ysize );
  95. assert( tr < xsize*ysize );
  96. if ( br >= xsize*ysize )
  97. {
  98. fprintf( stderr, "xsize=%d, ysize=%d, x=%d, y=%d, wsy=%d, wsx=%d\n",
  99. xsize, ysize, x, y, window_size_x, window_size_y );
  100. fprintf( stderr, "example: %d x %d\n",
  101. example->width, example->height );
  102. }
  103. assert( bl < xsize*ysize );
  104. assert( br < xsize*ysize );
  105. assert( pos1 >= 0 );
  106. assert( pos2 >= 0 );
  107. double value;
  108. if ( type == HaarFeature::HAARTYPE_HORIZONTAL )
  109. {
  110. long ml = tl + xsize * pos1;
  111. long mr = tr + xsize * pos1;
  112. assert(( ml >= 0 ) && ( ml < xsize*ysize ) );
  113. assert(( mr >= 0 ) && ( mr < xsize*ysize ) );
  114. value = 2 * integralImage[mr];
  115. value -= 2 * integralImage[ml];
  116. value += integralImage[tl];
  117. value += integralImage[tr];
  118. value -= integralImage[bl];
  119. value -= integralImage[br];
  120. } else if ( type == HaarFeature::HAARTYPE_VERTICAL ) {
  121. long mt = tl + pos1;
  122. long mb = bl + pos1;
  123. assert(( mt >= 0 ) && ( mt < xsize*ysize ) );
  124. assert(( mb >= 0 ) && ( mb < xsize*ysize ) );
  125. value = 2 * integralImage[mb];
  126. value -= 2 * integralImage[mt];
  127. value += integralImage[tl];
  128. value += integralImage[tr];
  129. value -= integralImage[bl];
  130. value -= integralImage[br];
  131. } else if ( type == HaarFeature::HAARTYPE_DIAGONAL ) {
  132. int p2o = pos2 * xsize;
  133. assert(( p2o >= 0 ) && ( p2o < xsize*ysize ) );
  134. assert(( tl + pos1 >= 0 ) && ( tl + pos1 < xsize*ysize ) );
  135. assert(( tl + p2o >= 0 ) && ( tl + p2o < xsize*ysize ) );
  136. assert(( bl + pos1 >= 0 ) && ( bl + pos1 < xsize*ysize ) );
  137. assert(( tr + p2o >= 0 ) && ( tr + p2o < xsize*ysize ) );
  138. assert(( tl + pos1 + p2o >= 0 ) && ( tl + pos1 + p2o < xsize*ysize ) );
  139. value = integralImage[tl];
  140. value += integralImage[bl];
  141. value += integralImage[br];
  142. value += integralImage[tr];
  143. value -= 2 * (
  144. integralImage[tl+pos1]
  145. + integralImage[tl+p2o]
  146. + integralImage[bl+pos1]
  147. + integralImage[tr+p2o]
  148. );
  149. value += 4 * integralImage[tl + pos1 + p2o];
  150. } else if ( type == HaarFeature::HAARTYPE_3BLOCKS ) {
  151. assert(( tl + pos1 >= 0 ) && ( tl + pos1 < xsize*ysize ) );
  152. assert(( bl + pos2 >= 0 ) && ( bl + pos2 < xsize*ysize ) );
  153. assert(( tl + pos2 >= 0 ) && ( tl + pos2 < xsize*ysize ) );
  154. assert(( bl + pos1 >= 0 ) && ( bl + pos1 < xsize*ysize ) );
  155. value = integralImage[tl];
  156. value += integralImage[br];
  157. value -= integralImage[bl];
  158. value -= integralImage[tr];
  159. value += 2 * (
  160. - integralImage[tl+pos1]
  161. - integralImage[bl+pos2]
  162. + integralImage[tl+pos2]
  163. + integralImage[bl+pos1]
  164. );
  165. } else {
  166. return -1;
  167. }
  168. assert( finite( value ) );
  169. return value;
  170. }
  171. void HaarFeature::restore( istream & is, int format )
  172. {
  173. is >> type;
  174. is >> window_size_x;
  175. is >> window_size_y;
  176. is >> pos1;
  177. is >> pos2;
  178. }
  179. void HaarFeature::store( ostream & os, int format ) const
  180. {
  181. os << "HAARFEATURE" << " " << type << " "
  182. << window_size_x << " " << window_size_y
  183. << " " << pos1 << " " << pos2;
  184. }
  185. void HaarFeature::clear()
  186. {
  187. // nothing to do in my opinion
  188. }