LFColorSande.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /**
  2. * @file LFColorSande.cpp
  3. * @brief interface to ColorSande implementation
  4. * @author Erik Rodner
  5. * @date 11/19/2007
  6. */
  7. #ifdef NOVISUAL
  8. #include <vislearning/nice_nonvis.h>
  9. #else
  10. #include <vislearning/nice.h>
  11. #endif
  12. #include <errno.h>
  13. #include <iostream>
  14. #include <core/image/Convert.h>
  15. #include "core/basics/StringTools.h"
  16. #include "core/basics/FileMgt.h"
  17. #include "vislearning/baselib/Globals.h"
  18. #include "vislearning/features/localfeatures/LFColorSande.h"
  19. #define DESCSIZE_DUMMY "/home/bachi/HiWi/nice/nice/objrec-froehlichexp/progs/IMG_8762.JPG"
  20. #include <sstream>
  21. using namespace OBJREC;
  22. using namespace std;
  23. using namespace NICE;
  24. LFColorSande::LFColorSande( const Config *conf, std::string section )
  25. {
  26. c_binaryExecutable = conf->gS( section, "binaryExecutable", "/home/bachi/libs/van_de_sande/x86_64-linux-gcc/colorDescriptor" );
  27. c_params = conf->gS(section, "params", "--descriptor opponentsift");
  28. scales = conf->gS(section, "scales", "1+1.5+3.0+4.5+6");
  29. descriptor_size = conf->gI(section, "descriptor_size", -1 );
  30. usegrid = conf->gB(section, "usegrid", false);
  31. int g = conf->gI( section, "grid", 5);
  32. std::ostringstream temp;
  33. temp << g;
  34. gridsize = temp.str();
  35. if ( descriptor_size <= 0 )
  36. {
  37. fprintf (stderr, "LFColorSande::LFColorSande: No descriptor size found in config -> self test\n");
  38. /** get feature dimension **/
  39. NICE::Image testimg (DESCSIZE_DUMMY);
  40. VVector features;
  41. VVector positions;
  42. extractFeatures ( testimg, features, positions );
  43. if ( features.size() <= 0 )
  44. fthrow( Exception, "No features found in " << DESCSIZE_DUMMY << " picture.");
  45. descriptor_size = features[0].size();
  46. fprintf (stderr, "LFColorSande::LFColorSande Self Test features:%d dimension:%d\n", (int)features.size(), descriptor_size );
  47. }
  48. if ( descriptor_size != conf->gI("features", "descriptor_size", descriptor_size) )
  49. {
  50. cerr << "Warning: LFColorSande: descriptor sizes do not match !!!" << endl;
  51. }
  52. }
  53. LFColorSande::~LFColorSande()
  54. {
  55. }
  56. int LFColorSande::getDescSize () const
  57. {
  58. return descriptor_size;
  59. }
  60. int LFColorSande::extractFeatures ( const NICE::Image & img, VVector & features,
  61. VVector & positions ) const
  62. {
  63. cerr << "Warning: LFColorSande is a color local feature implementation, but you are calling the gray-image version of extractFeatures" << endl;
  64. NICE::ColorImage colorimg;
  65. NICE::grayToRGB (img, &colorimg);
  66. extractFeatures( colorimg, features, positions);
  67. return 0;
  68. }
  69. int LFColorSande::extractFeatures ( const NICE::ColorImage & img, VVector & features, VVector & positions ) const
  70. {
  71. if(features.size() != positions.size())
  72. {
  73. positions.clear();
  74. }
  75. bool delete_imgfile = false;
  76. std::string imgfile = Globals::getCurrentImgFN();
  77. fprintf (stderr, "imgfile: %s\n", imgfile.c_str());
  78. if ( (imgfile.size() <= 0) || (( !StringTools::regexMatch ( imgfile, ".[Jj][pP][Gg]$" ) )
  79. && ( !StringTools::regexMatch ( imgfile, ".[Pp][Nn][Gg]$" ))))
  80. {
  81. if ( imgfile.size() <= 0 )
  82. {
  83. imgfile = FileMgt::createTempFile ( "/tmp/osl_lfColorSande_input_%s.png" );
  84. fprintf (stderr, "LFColorSande: write image to %s (write image)\n", imgfile.c_str() );
  85. ImageFile imgf ( imgfile );
  86. imgf.writer ( &img );
  87. } else {
  88. std::string tmpfile = FileMgt::createTempFile ( "/tmp/osl_lfColorSande_input_%s.png" );
  89. fprintf (stderr, "LFColorSande: write image to %s (convert)\n", tmpfile.c_str() );
  90. std::string convertcall = "convert " + imgfile + " " + tmpfile;
  91. cerr << "convert call: " << convertcall << endl;
  92. system ( convertcall.c_str() );
  93. imgfile = tmpfile;
  94. }
  95. delete_imgfile = true;
  96. }
  97. std::string outputfn = FileMgt::createTempFile ( "/tmp/osl_lfColorSande_output_%s" ) ;
  98. std::string gridparams ="";
  99. if(usegrid)
  100. gridparams = " --detector densesampling --ds_spacing " + gridsize +" --ds_scales "+scales;
  101. std::string call = c_binaryExecutable + " " +
  102. imgfile + " " +
  103. c_params +
  104. gridparams +
  105. " -output " + outputfn;
  106. cerr << "LFColorSande: parameters: <" << c_params+gridparams << ">" << endl;
  107. clog << "Systemcall: " << call << endl;
  108. const int buffersize = 65536;
  109. char *buffer = new char [buffersize];
  110. FILE *f = popen ( call.c_str(), "r" );
  111. if ( f == NULL )
  112. {
  113. fthrow(Exception, "Unable to run the implementation of van de Sande: " << call << endl << strerror(errno) );
  114. }
  115. while ( ! feof(f) )
  116. {
  117. if ( fgets ( buffer, buffersize, f ) <= 0 )
  118. {
  119. break;
  120. } else {
  121. fprintf (stderr, "LFColorSande::extractFeatures: [INFO] %s", buffer );
  122. }
  123. }
  124. pclose(f);
  125. f = fopen ( outputfn.c_str(), "r" );
  126. if ( f == NULL )
  127. {
  128. fthrow( Exception, "Unable to read output of van de Sande implementation\n");
  129. }
  130. if ( fgets ( buffer, buffersize, f ) <= 0 )
  131. {
  132. fprintf (stderr, "LFColorSande::extractFeatures: output is empty !\n");
  133. fprintf (stderr, "img %s out %s\n", imgfile.c_str(), outputfn.c_str() );
  134. fprintf (stderr, "call %s\n", call.c_str() );
  135. exit(-1);
  136. }
  137. if ( ! strcmp(buffer, "KOEN1" ) )
  138. {
  139. fprintf (stderr, "LFColorSande::extractFeatures: wrong file format\n");
  140. fprintf (stderr, "img %s out %s\n", imgfile.c_str(), outputfn.c_str() );
  141. fprintf (stderr, "call %s\n", call.c_str() );
  142. exit(-1);
  143. }
  144. fgets ( buffer, buffersize, f );
  145. int dimension = atoi (buffer);
  146. fprintf (stderr, "LFColorSande: descriptor dimension = %d\n", dimension );
  147. if ( (descriptor_size > 0) && (dimension != descriptor_size) )
  148. {
  149. fprintf (stderr, "LFColorSande::extractFeatures: dimensions do not match %d -> %d!\n",
  150. dimension, descriptor_size);
  151. fprintf (stderr, "img %s out %s\n", imgfile.c_str(), outputfn.c_str() );
  152. fprintf (stderr, "call %s\n", call.c_str() );
  153. fprintf (stderr, "dimension std::string buffer: \"%s\"", buffer );
  154. exit(-1);
  155. }
  156. fgets ( buffer, buffersize, f );
  157. int noDesc = atoi (buffer);
  158. fprintf (stderr, "LFColorSande::extractFeatures: no. of descriptors = %d\n", noDesc );
  159. NICE::Vector x;
  160. while ( ! feof(f) )
  161. {
  162. // <CIRCLE 119 307 1.26134 0 0.00014763>; 0 0 6 2 0 6 25 7 9 4 4 0 0 4 20 36 78 4 5 0 0
  163. if ( fgets(buffer, buffersize, f) == NULL )
  164. break;
  165. const char *buffer_data = strchr ( buffer, ';' );
  166. if ( strlen(buffer_data) <= 0 )
  167. {
  168. fprintf (stderr, "LFColorSande::extractFeatures: it seems you forget to specify a descriptor\n");
  169. exit(-1);
  170. }
  171. const char *buffer_key_start = strchr ( buffer, ' ' );
  172. const char *buffer_key_end = strchr ( buffer, '>' );
  173. buffer_key_start++;
  174. int keylen = buffer_key_end - buffer_key_start;
  175. char *key = new char [keylen+1];
  176. strncpy ( key, buffer_key_start, keylen );
  177. key[keylen] = '\0';
  178. buffer_data+=2;
  179. std::string buffer_data_s (buffer_data);
  180. //clog << "[log] buffer = " << buffer_data_s << endl;
  181. StringTools::splitVector ( buffer_data_s, ' ', x );
  182. if ( (int)x.size() != dimension )
  183. {
  184. cerr << "Line = " << buffer_data_s << endl;
  185. cerr << "Vector = " << x << endl;
  186. cerr << "dimension = " << dimension << endl;
  187. cerr << "x.size() = " << x.size() << endl;
  188. fprintf (stderr, "LFColorSande::extractFeatures: error parsing output !!\n");
  189. exit(-1);
  190. } else {
  191. NICE::Vector pos;
  192. StringTools::splitVector ( key, ' ', pos );
  193. if ( pos.size() != 5 ) {
  194. fprintf (stderr, "LFColorSande::extractFeatures: dimension mismatch (position information)\n");
  195. exit(-1);
  196. }
  197. // Van De Sande verwendet MatLab-Darstellung der Koordinaten. Diese fangen bei 1 an und nicht bei 0.
  198. pos[0] --;
  199. pos[1] --;
  200. positions.push_back( pos );
  201. features.push_back ( x );
  202. }
  203. }
  204. fclose (f);
  205. if ( delete_imgfile )
  206. FileMgt::deleteTempFile ( imgfile );
  207. FileMgt::deleteTempFile ( outputfn );
  208. delete [] buffer;
  209. return 0;
  210. }