LocalFeatureSift.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. /**
  2. * @file LocalFeatureSift.cpp
  3. * @brief local feature with sift
  4. * @author Erik Rodner, Alexander Freytag
  5. * @date 03/10/2012
  6. */
  7. #include <iostream>
  8. #include "vislearning/features/localfeatures/sift.h"
  9. #include "vislearning/features/localfeatures/LocalFeatureSift.h"
  10. using namespace OBJREC;
  11. using namespace std;
  12. using namespace NICE;
  13. ///////////////////// ///////////////////// /////////////////////
  14. // CONSTRUCTORS / DESTRUCTORS
  15. ///////////////////// ///////////////////// /////////////////////
  16. LocalFeatureSift::LocalFeatureSift() : LocalFeature ()
  17. {
  18. this->octaves = 6;
  19. this->levels = 3;
  20. this->first_octave = -1;
  21. this->normalizeFeature = true;
  22. this->magnif = 3;
  23. this->deletemode = true;
  24. this->integerValues = true;
  25. this->usegpu = false;
  26. }
  27. LocalFeatureSift::LocalFeatureSift( const NICE::Config * _conf )
  28. {
  29. this->initFromConfig( _conf );
  30. }
  31. LocalFeatureSift::~LocalFeatureSift()
  32. {
  33. }
  34. void OBJREC::LocalFeatureSift::initFromConfig( const NICE::Config* _conf, const std::string& _confSection )
  35. {
  36. //NOTE previous confSection defaultet to LFSiftPP!
  37. this->octaves = _conf->gI(_confSection, "octaves", 6);
  38. this->levels = _conf->gI(_confSection, "levels", 3);
  39. this->first_octave = _conf->gI(_confSection, "first_octave", -1);
  40. this->normalizeFeature = _conf->gB(_confSection, "normalize_feature", true );
  41. this->magnif = _conf->gD(_confSection, "magnif", 3 );
  42. this->deletemode = _conf->gB(_confSection, "deletemode", true );
  43. this->integerValues = _conf->gB(_confSection, "integer_values", true );
  44. #ifdef NICE_USELIB_CUDASIFT
  45. this->usegpu = _conf->gB(_confSection, "use_siftgpu", false );
  46. #else
  47. this->usegpu = false;
  48. #endif
  49. }
  50. ///////////////////// ///////////////////// /////////////////////
  51. // FEATURE STUFF
  52. ///////////////////// ///////////////////// //////////////////
  53. void LocalFeatureSift::sortPositions(VVector & positions) const
  54. {
  55. // < Key , Val >
  56. map<double, bool> scales;
  57. for ( vector< NICE::Vector >::iterator i = positions.begin();
  58. i != positions.end();i++)
  59. {
  60. const NICE::Vector & pos = *i;
  61. scales[pos[2]] = true;
  62. }
  63. VVector newpositions;
  64. map<double,bool>::iterator iter;
  65. for ( iter = scales.begin(); iter != scales.end(); ++iter )
  66. {
  67. for ( vector< NICE::Vector >::iterator i = positions.begin();
  68. i != positions.end();i++)
  69. {
  70. const NICE::Vector & pos = *i;
  71. if (pos[2] == iter->first)
  72. {
  73. newpositions.push_back(pos);
  74. }
  75. }
  76. }
  77. positions = newpositions;
  78. }
  79. void LocalFeatureSift::computeDesc( const NICE::Image & img, VVector & positions, VVector & descriptors ) const
  80. {
  81. if ( usegpu ) {
  82. try {
  83. #ifdef NICE_USELIB_CUDASIFT
  84. withGPU( img, positions, descriptors );
  85. #endif
  86. }
  87. catch ( runtime_error& rte ) {
  88. cerr << "[err] LocalFeatureSift: " << rte.what() << endl;
  89. clog << "[log] use SIFTPP implementation:" << endl;
  90. withPP( img, positions, descriptors );
  91. }
  92. }
  93. else {
  94. withPP( img, positions, descriptors );
  95. }
  96. }
  97. int LocalFeatureSift::getDescriptors ( const NICE::Image & img, VVector & positions, VVector & descriptors ) const
  98. {
  99. sortPositions(positions);
  100. computeDesc(img, positions, descriptors);
  101. return 0;
  102. }
  103. void LocalFeatureSift::visualizeFeatures ( NICE::Image & mark, const VVector & positions, size_t color ) const
  104. {
  105. /* TODO: switch to NICE instead of ICE
  106. ice::Image mark_ice = ice::NewImg ( mark.width(),
  107. mark.height(), 255 );
  108. for ( size_t k = 0 ; k < positions.size() ; k++ )
  109. {
  110. const NICE::Vector & pos = positions[k];
  111. ice::Matrix points ( 0, 2 );
  112. const int size = 6;
  113. points.Append ( ice::Vector(-size, -size) );
  114. points.Append ( ice::Vector(-size, size) );
  115. points.Append ( ice::Vector(size, size) );
  116. points.Append ( ice::Vector(size, -size) );
  117. ice::Trafo tr;
  118. tr.Scale ( 0, 0, pos[2] );
  119. tr.Rotate ( 0, 0, pos[3] );
  120. tr.Shift ( pos[0], pos[1] );
  121. ice::TransformList(tr, points);
  122. for ( int j = 0 ; j < points.rows(); j++ )
  123. {
  124. if (points[j][0] < 0 )
  125. points[j][0] = 0;
  126. if (points[j][0] >= mark_ice->xsize)
  127. points[j][0] = mark_ice->xsize - 1;
  128. if (points[j][1] < 0 )
  129. points[j][1] = 0;
  130. if (points[j][1] >= mark_ice->ysize)
  131. points[j][1] = mark_ice->ysize - 1;
  132. }
  133. ice::DrawPolygon ( points, color, mark_ice );
  134. }
  135. for ( unsigned int y = 0 ; y < mark.height(); y++ )
  136. for ( unsigned int x = 0 ; x < mark.width(); x++ )
  137. mark.setPixel(x,y, GetVal(mark_ice,x,y));*/
  138. }
  139. void LocalFeatureSift::withPP( const NICE::Image & img, VVector & positions, VVector & descriptors ) const
  140. {
  141. int O = octaves ;
  142. int const S = levels ;
  143. int const omin = first_octave;
  144. float const sigman = .5 ; //.5
  145. float const sigma0 = 1.6 * powf(2.0f, 1.0f / S) ;
  146. if (O < 1)
  147. {
  148. O = std::max(int(std::floor(log2
  149. (std::min(img.width(),img.height()))) - omin - 3), 1) ;
  150. }
  151. const unsigned char *blockimg = (unsigned char*) img.getPixelPointer();
  152. float *blockimgfl = new float[img.width() * img.height()];
  153. for ( int k = 0 ; k < img.width() * img.height() ; k++ )
  154. blockimgfl[k] = blockimg[k];
  155. VL::Sift sift( blockimgfl, img.width(), img.height(),
  156. sigman, sigma0, O, S, omin, -1, S+1) ;
  157. //calling sift.process(.) already done in VL::Sift constructor, so omit the following process function
  158. //sift.process ( blockimgfl, img.width(), img.height() );
  159. sift.setMagnification ( magnif );
  160. sift.setNormalizeDescriptor ( normalizeFeature );
  161. const int descr_size = 128;
  162. VL::float_t *descr_pt = new VL::float_t [descr_size];
  163. VL::float_t angles[4] ;
  164. NICE::Vector feature (descr_size);
  165. NICE::Vector pos ( 4 );
  166. for ( vector< NICE::Vector >::iterator i = positions.begin();
  167. i != positions.end();)
  168. {
  169. const NICE::Vector & pos = *i;
  170. double x = pos[0];
  171. double y = pos[1];
  172. assert(pos[0] < img.width());
  173. assert(pos[1] < img.height());
  174. double s = pos[2];
  175. bool deleteFeature = false;
  176. VL::Sift::Keypoint kp = sift.getKeypoint (x,y,s);
  177. double angle = 0.0;
  178. if ( pos.size() < 4 )
  179. {
  180. int nangles = sift.computeKeypointOrientations(angles, kp);
  181. if ( nangles > 0 )
  182. {
  183. angle = angles[0];
  184. }
  185. else
  186. {
  187. if (deletemode)
  188. deleteFeature = true;
  189. else
  190. angle = 0;
  191. }
  192. }
  193. else
  194. {
  195. angle = pos[3];
  196. }
  197. if ( ! deleteFeature )
  198. {
  199. sift.computeKeypointDescriptor ( descr_pt, kp, angle );
  200. for ( int j = 0 ; j < descr_size ; j++ )
  201. // Umwandlung in Integer moegl.
  202. feature[j] = (integerValues ? (int)(512*descr_pt[j]) : descr_pt[j]);
  203. descriptors.push_back ( feature );
  204. i++;
  205. }
  206. else
  207. {
  208. i = positions.erase(i);
  209. }
  210. }
  211. delete [] blockimgfl;
  212. delete [] descr_pt;
  213. }
  214. #ifdef NICE_USELIB_CUDASIFT
  215. void LocalFeatureSift::withGPU(const NICE::Image& img, VVector& positions, VVector& descriptors) const
  216. {
  217. // fill the parameter for
  218. char* argv[] = {
  219. // First octave to detect DOG keypoints
  220. "-fo" , const_cast<char*> (StringTools::convertToString<int> (first_octave).c_str()),
  221. // Maximum number of Octaves
  222. "-no" , const_cast<char*> (StringTools::convertToString<int> (octaves).c_str()),
  223. // Number of DOG levels in an octave.
  224. "-d" , const_cast<char*> (StringTools::convertToString<int> (levels).c_str()),
  225. // Write unnormalized descriptor if specified.
  226. const_cast<char*> (normalizeFeature ? "" : "-unn"),
  227. // Descriptor grid size factor (magnif ??)
  228. "-dw" , const_cast<char*> (StringTools::convertToString<float> (magnif).c_str()),
  229. // verbose levels
  230. "-v", "0"
  231. };
  232. int argc = sizeof (argv) / sizeof (char*);
  233. // sift Instanz
  234. SiftGPU sift;
  235. // give parameter to sift
  236. sift.ParseParam (argc, argv);
  237. // check, whether siftgpu is full supported
  238. int support = sift.CreateContextGL();
  239. if( support != SiftGPU::SIFTGPU_FULL_SUPPORTED )
  240. throw runtime_error( "SiftGPU-support is not given by your device.");
  241. // set keypoints
  242. const int numberOfKeypoints = positions.size();
  243. SiftGPU::SiftKeypoint keys[numberOfKeypoints];
  244. // copy the NICEKeypoints into SiftKeypoints
  245. for (int i = 0; i < numberOfKeypoints; i++) {
  246. keys[i].x = positions[i][0];
  247. keys[i].y = positions[i][1];
  248. keys[i].s = positions[i][2];
  249. keys[i].o = positions[i][3];
  250. }
  251. sift.SetKeypointList (numberOfKeypoints, keys);
  252. // run SIFT
  253. const int imageWidth = img.width();
  254. const int imageHeight = img.height();
  255. const unsigned char* rawImageData = img.getPixelPointer();
  256. sift.RunSIFT (imageWidth, imageHeight, rawImageData, GL_LUMINANCE, GL_UNSIGNED_BYTE);
  257. // get descriptors
  258. const int descr_size = 128;
  259. const int numberOfDescriptors = sift.GetFeatureNum();
  260. float desc[descr_size * numberOfDescriptors];
  261. sift.GetFeatureVector (NULL, desc);
  262. Vector localDesc (descr_size);
  263. // copy the SiftDescriptors into NICEDescriptors
  264. for (int i = 0; i < numberOfDescriptors; i++) {
  265. for (int j = 0; j < descr_size; j++) {
  266. localDesc[j] = (integerValues ? (int) (512 * desc[i*descr_size+j]) : desc[i*descr_size+j]);
  267. }
  268. descriptors.push_back (localDesc);
  269. }
  270. }
  271. #endif
  272. ///////////////////// INTERFACE PERSISTENT /////////////////////
  273. // interface specific methods for store and restore
  274. ///////////////////// INTERFACE PERSISTENT /////////////////////
  275. void LocalFeatureSift::restore ( std::istream & is, int format )
  276. {
  277. //delete everything we knew so far...
  278. this->clear();
  279. if ( is.good() )
  280. {
  281. std::string tmp;
  282. is >> tmp; //class name
  283. if ( ! this->isStartTag( tmp, "LocalFeatureSift" ) )
  284. {
  285. std::cerr << " WARNING - attempt to restore LocalFeatureSift, but start flag " << tmp << " does not match! Aborting... " << std::endl;
  286. throw;
  287. }
  288. bool b_endOfBlock ( false ) ;
  289. while ( !b_endOfBlock )
  290. {
  291. is >> tmp; // start of block
  292. if ( this->isEndTag( tmp, "LocalFeatureSift" ) )
  293. {
  294. b_endOfBlock = true;
  295. continue;
  296. }
  297. tmp = this->removeStartTag ( tmp );
  298. if ( tmp.compare("octaves") == 0 )
  299. {
  300. is >> this->octaves;
  301. is >> tmp; // end of block
  302. tmp = this->removeEndTag ( tmp );
  303. }
  304. else if ( tmp.compare("levels") == 0 )
  305. {
  306. is >> this->levels;
  307. is >> tmp; // end of block
  308. tmp = this->removeEndTag ( tmp );
  309. }
  310. else if ( tmp.compare("first_octave") == 0 )
  311. {
  312. is >> this->first_octave;
  313. is >> tmp; // end of block
  314. tmp = this->removeEndTag ( tmp );
  315. }
  316. else if ( tmp.compare("normalizeFeature") == 0 )
  317. {
  318. is >> this->normalizeFeature;
  319. is >> tmp; // end of block
  320. tmp = this->removeEndTag ( tmp );
  321. }
  322. else if ( tmp.compare("magnif") == 0 )
  323. {
  324. is >> this->magnif;
  325. is >> tmp; // end of block
  326. tmp = this->removeEndTag ( tmp );
  327. }
  328. else if ( tmp.compare("deletemode") == 0 )
  329. {
  330. is >> this->deletemode;
  331. is >> tmp; // end of block
  332. tmp = this->removeEndTag ( tmp );
  333. }
  334. else if ( tmp.compare("integerValues") == 0 )
  335. {
  336. is >> this->integerValues;
  337. is >> tmp; // end of block
  338. tmp = this->removeEndTag ( tmp );
  339. }
  340. else if ( tmp.compare("usegpu") == 0 )
  341. {
  342. is >> this->usegpu;
  343. is >> tmp; // end of block
  344. tmp = this->removeEndTag ( tmp );
  345. }
  346. else
  347. {
  348. std::cerr << "WARNING -- unexpected LocalFeatureSift object -- " << tmp << " -- for restoration... aborting" << std::endl;
  349. throw;
  350. }
  351. }
  352. }
  353. else
  354. {
  355. std::cerr << "LocalFeatureSift::restore -- InStream not initialized - restoring not possible!" << std::endl;
  356. throw;
  357. }
  358. }
  359. void LocalFeatureSift::store ( std::ostream & os, int format ) const
  360. {
  361. if (os.good())
  362. {
  363. // show starting point
  364. os << this->createStartTag( "LocalFeatureSift" ) << std::endl;
  365. os << this->createStartTag( "octaves" ) << std::endl;
  366. os << this->octaves << std::endl;
  367. os << this->createEndTag( "octaves" ) << std::endl;
  368. os << this->createStartTag( "levels" ) << std::endl;
  369. os << this->levels << std::endl;
  370. os << this->createEndTag( "levels" ) << std::endl;
  371. os << this->createStartTag( "first_octave" ) << std::endl;
  372. os << this->first_octave << std::endl;
  373. os << this->createEndTag( "first_octave" ) << std::endl;
  374. os << this->createStartTag( "normalizeFeature" ) << std::endl;
  375. os << this->normalizeFeature << std::endl;
  376. os << this->createEndTag( "normalizeFeature" ) << std::endl;
  377. os << this->createStartTag( "magnif" ) << std::endl;
  378. os << this->magnif << std::endl;
  379. os << this->createEndTag( "magnif" ) << std::endl;
  380. os << this->createStartTag( "deletemode" ) << std::endl;
  381. os << this->deletemode << std::endl;
  382. os << this->createEndTag( "deletemode" ) << std::endl;
  383. os << this->createStartTag( "integerValues" ) << std::endl;
  384. os << this->integerValues << std::endl;
  385. os << this->createEndTag( "integerValues" ) << std::endl;
  386. os << this->createStartTag( "usegpu" ) << std::endl;
  387. os << this->usegpu << std::endl;
  388. os << this->createEndTag( "usegpu" ) << std::endl;
  389. // done
  390. os << this->createEndTag( "LocalFeatureSift" ) << std::endl;
  391. }
  392. else
  393. {
  394. std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
  395. }
  396. }
  397. void LocalFeatureSift::clear ()
  398. {
  399. }