LFSiftPP.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /**
  2. * @file LFSiftPP.cpp
  3. * @brief Sift++ interface
  4. * @author Erik Rodner
  5. * @date 11/19/2007
  6. */
  7. #include <iostream>
  8. #include <sstream>
  9. // #ifdef NICE_USELIB_ICE
  10. // #include <image_nonvis.h>
  11. // #endif
  12. #include "vislearning/features/localfeatures/LFSiftPP.h"
  13. #include "core/basics/Exception.h"
  14. using namespace std;
  15. using namespace NICE;
  16. #include "vislearning/features/localfeatures/sift.h"
  17. using namespace OBJREC;
  18. LFSiftPP::LFSiftPP( const Config *conf )
  19. {
  20. threshold = conf->gD("LFSiftPP", "threshold", 0.0);
  21. edgeThreshold = conf->gD("LFSiftPP", "edge_threshold", 10.0);
  22. octaves = conf->gI("LFSiftPP", "octaves", 6);
  23. first_octave = conf->gI("LFSiftPP", "first_octave", -1);
  24. levels = conf->gI("LFSiftPP", "levels", 3);
  25. minScale = conf->gD("LFSiftPP", "min_scale", 1);
  26. maxScale = conf->gD("LFSiftPP", "max_scale", 4);
  27. numScales = conf->gI("LFSiftPP", "num_scales", 10);
  28. numAngles = conf->gI("LFSiftPP", "num_angles", 6 );
  29. std::string descriptorAlignment_s = conf->gS("LFSiftPP", "descriptor_alignment", "detector" );
  30. if ( descriptorAlignment_s == "detector" )
  31. descriptorAlignment = DALGIN_DETECTOR;
  32. else if ( descriptorAlignment_s == "multiple" )
  33. descriptorAlignment = DALIGN_MULTIPLE;
  34. else {
  35. fprintf (stderr, "LFSiftPP: descriptor alignment method unknown !\n");
  36. exit(-1);
  37. }
  38. normalizeFeature = conf->gB("LFSiftPP", "normalize_feature", false );
  39. std::ostringstream os;
  40. os << "siftpp_" << "l" << levels << "_o"
  41. << octaves << "_m" << minScale << "_t"
  42. << threshold << "_e" << edgeThreshold;
  43. if ( ! normalizeFeature )
  44. os << "_nd";
  45. }
  46. LFSiftPP::~LFSiftPP()
  47. {
  48. }
  49. int LFSiftPP::getDescSize () const
  50. {
  51. return 128;
  52. }
  53. int LFSiftPP::extractFeatures ( const NICE::Image & img, VVector & features,
  54. VVector & positions ) const
  55. {
  56. int O = octaves ;
  57. int const S = levels ;
  58. int const omin = first_octave;
  59. float const sigman = .5 ;
  60. float const sigma0 = 1.6 * powf(2.0f, 1.0f / S) ;
  61. if (O < 1) {
  62. O = std::max
  63. (int
  64. (std::floor
  65. (log2
  66. (std::min(img.width(),img.height()))) - omin -3), 1) ;
  67. }
  68. const unsigned char *blockimg = (unsigned char*) img.getPixelPointer();
  69. if ( blockimg == NULL ) {
  70. fprintf (stderr, "FATAL ERROR: do not use subimages !!\n");
  71. exit(-1);
  72. }
  73. float *blockimgfl = new float[img.width() * img.height()];
  74. for ( int k = 0 ; k < img.width() * img.height() ; k++ )
  75. blockimgfl[k] = blockimg[k];
  76. VL::Sift sift( blockimgfl, img.width(), img.height(),
  77. sigman, sigma0, O, S, omin, -1, S+1) ;
  78. sift.process ( blockimgfl, img.width(), img.height() );
  79. // compute keypoints
  80. sift.detectKeypoints(threshold, edgeThreshold) ;
  81. const int descr_size = 128;
  82. VL::float_t *descr_pt = new VL::float_t [descr_size];
  83. VL::float_t angles[4] ;
  84. int keypointCount = 0;
  85. const int maxKeyPoints = std::numeric_limits<int>::max();
  86. NICE::Vector feature (descr_size);
  87. for( VL::Sift::KeypointsConstIter iter = sift.keypointsBegin() ;
  88. iter != sift.keypointsEnd() ; ++iter, keypointCount++ )
  89. {
  90. if ( keypointCount >= maxKeyPoints ) break;
  91. if ( descriptorAlignment == DALGIN_DETECTOR )
  92. {
  93. if ( iter->s < minScale ) continue;
  94. int nangles = sift.computeKeypointOrientations(angles, *iter);
  95. for ( int i = 0 ; i < nangles ; i++ )
  96. {
  97. sift.computeKeypointDescriptor ( descr_pt, *iter, angles[i] );
  98. for ( int j = 0 ; j < descr_size ; j++ )
  99. {
  100. if ( isnan(descr_pt[j]) ) {
  101. fprintf (stderr, "Descriptor with NAN values !!\n");
  102. exit(-1);
  103. } else {
  104. feature[j] = descr_pt[j];
  105. }
  106. }
  107. NICE::Vector p (4);
  108. p[0] = iter->x;
  109. p[1] = iter->y;
  110. p[2] = iter->s;
  111. p[3] = angles[i];
  112. positions.push_back(p);
  113. if ( normalizeFeature )
  114. feature.normalizeL2();
  115. features.push_back ( feature );
  116. }
  117. } else if ( descriptorAlignment == DALIGN_MULTIPLE ) {
  118. double angle_step = 2 * M_PI / numAngles;
  119. double scale_step = (maxScale - minScale) / numScales;
  120. for ( int j = 0 ; j < numAngles ; j++ )
  121. {
  122. double scale = j * scale_step;
  123. for ( int i = 0 ; i < numAngles ; i++ )
  124. {
  125. double angle = angle_step * i;
  126. sift.computeKeypointDescriptor ( descr_pt, *iter, angle );
  127. for ( int j = 0 ; j < descr_size ; j++ )
  128. {
  129. if ( isnan(descr_pt[j]) ) {
  130. fprintf (stderr, "Descriptor with NAN values !!\n");
  131. exit(-1);
  132. } else {
  133. feature[j] = descr_pt[j];
  134. }
  135. }
  136. NICE::Vector p (4);
  137. p[0] = iter->x;
  138. p[1] = iter->y;
  139. p[2] = iter->s;
  140. p[3] = angles[i];
  141. positions.push_back(p);
  142. if ( normalizeFeature )
  143. feature.normalizeL2();
  144. features.push_back ( feature );
  145. }
  146. }
  147. }
  148. }
  149. fprintf (stderr, "LFSiftpp::convert: Number of Keypoints = %d\n", keypointCount );
  150. delete [] blockimgfl;
  151. delete [] descr_pt;
  152. if ( keypointCount <= 0 )
  153. fprintf (stderr, "FATAL ERROR: no keypoints found !!\n");
  154. return 0;
  155. }
  156. void LFSiftPP::visualizeFeatures ( NICE::Image & mark,
  157. const VVector & positions,
  158. size_t color ) const
  159. {
  160. fthrow(Exception, "LFSiftPP::visualizeFeatures -- not yet implemented due to old ICE version.");
  161. // #ifdef NICE_USELIB_ICE
  162. // ice::Image mark_ice = ice::NewImg ( mark.width(),
  163. // mark.height(), 255 );
  164. // for ( size_t k = 0 ; k < positions.size() ; k++ )
  165. // {
  166. // const NICE::Vector & pos = positions[k];
  167. // ice::Matrix points ( 0, 2 );
  168. // const int size = 6;
  169. // points.Append ( ice::Vector(-size, -size) );
  170. // points.Append ( ice::Vector(-size, size) );
  171. // points.Append ( ice::Vector(size, size) );
  172. // points.Append ( ice::Vector(size, -size) );
  173. //
  174. // ice::Trafo tr;
  175. //
  176. // tr.Scale ( 0, 0, pos[2] );
  177. // tr.Rotate ( 0, 0, pos[3] );
  178. // tr.Shift ( pos[0], pos[1] );
  179. //
  180. // ice::TransformList(tr, points);
  181. //
  182. // for ( int j = 0 ; j < points.rows(); j++ )
  183. // {
  184. // if (points[j][0] < 0 )
  185. // points[j][0] = 0;
  186. // if (points[j][0] >= mark_ice->xsize)
  187. // points[j][0] = mark_ice->xsize - 1;
  188. // if (points[j][1] < 0 )
  189. // points[j][1] = 0;
  190. // if (points[j][1] >= mark_ice->ysize)
  191. // points[j][1] = mark_ice->ysize - 1;
  192. // }
  193. //
  194. // ice::DrawPolygon ( points, color, mark_ice );
  195. // }
  196. //
  197. // for ( unsigned int y = 0 ; y < mark.height(); y++ )
  198. // for ( unsigned int x = 0 ; x < mark.width(); x++ )
  199. // mark.setPixel(x,y, GetVal(mark_ice,x,y));
  200. // #else
  201. // cerr << "uses ice visualization, please install ice or change to NICE visualization" << endl;
  202. // #endif
  203. //TODO check this!
  204. }