HaarFeature.cpp 6.3 KB

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