testFeatureLearning.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /**
  2. * @file testFeatureLearning.cpp
  3. * @brief test the feature learning routines to incrementally increase / adapt the codebook currently used
  4. * @author Alexander Freytag
  5. * @date 11-04-2013
  6. */
  7. //STL
  8. #include <iostream>
  9. #include <limits>
  10. //core
  11. #include <core/basics/Config.h>
  12. #include <core/basics/ResourceStatistics.h>
  13. #include <core/image/Convert.h>
  14. #include <core/vector/VectorT.h>
  15. //vislearning
  16. #include <vislearning/baselib/Globals.h>
  17. #include <vislearning/baselib/ICETools.h>
  18. #include <vislearning/cbaselib/MultiDataset.h>
  19. #include <vislearning/cbaselib/Example.h>
  20. //
  21. #include "vislearning/featureLearning/FeatureLearningGeneric.h"
  22. #include "vislearning/featureLearning/FeatureLearningClusterBased.h"
  23. #include "vislearning/featureLearning/FeatureLearningRegionBased.h"
  24. using namespace std;
  25. using namespace NICE;
  26. using namespace OBJREC;
  27. /**
  28. test feature learning routines
  29. */
  30. int main( int argc, char **argv )
  31. {
  32. std::set_terminate( __gnu_cxx::__verbose_terminate_handler );
  33. Config * conf = new Config ( argc, argv );
  34. bool showTrainingImages= conf->gB( "featureLearning", "showTrainingImages", false );
  35. bool showTestImages= conf->gB( "featureLearning", "showTestImages", false );
  36. ResourceStatistics rs;
  37. std::string resultdir;
  38. resultdir = conf->gS( "featureLearning", "resultdir", "/tmp/");
  39. //**********************************************
  40. //
  41. // READ INITIAL TRAINING SET TO COMPUTE
  42. // AN INITIAL CODEBOOK
  43. //
  44. //**********************************************
  45. std::cerr << " READ INITIAL TRAINING SET TO COMPUTE AN INITIAL CODEBOOK" << std::endl;
  46. MultiDataset md( conf );
  47. const LabeledSet *trainFiles = md["train"];
  48. //**********************************************
  49. //
  50. // SET UP THE FEATURE LEARNING ALGO
  51. //
  52. //**********************************************
  53. OBJREC::FeatureLearningGeneric * featureLearning;
  54. std::string featureLearningMethod = conf->gS( "featureLearning", "featureLearningMethod", "clusterBased" );
  55. if (featureLearningMethod.compare("clusterBased") == 0)
  56. {
  57. featureLearning = new OBJREC::FeatureLearningClusterBased( conf, &md );
  58. }
  59. else if (featureLearningMethod.compare("regionBased") == 0)
  60. {
  61. featureLearning = new OBJREC::FeatureLearningRegionBased( conf, &md );
  62. }
  63. else
  64. {
  65. std::cerr << "Unknown feature learning algorithm selected, use cluster based instead" << std::endl;
  66. featureLearning = new OBJREC::FeatureLearningClusterBased( conf, &md );
  67. }
  68. //print computed cluster centers -- this is NOT recommended :)
  69. // prototypes.store(std::cerr);
  70. //evaluate how well the training images are covered with our initial codebook
  71. //that is, compute these nice "novelty maps" per feature
  72. //NOTE we skip this currently
  73. LOOP_ALL_S( *trainFiles )
  74. {
  75. EACH_INFO( classno, info );
  76. std::string filename = info.img();
  77. //
  78. // featureLearning->evaluateCurrentCodebook( filename , true /* beforeComputingNewFeatures */);
  79. NICE::ImageT< int > imgClusterAssignments;
  80. imgClusterAssignments = featureLearning->evaluateCurrentCodebookByAssignments(filename , false /* beforeComputingNewFeatures */, false /* _binaryShowLatestPrototype*/ );
  81. NICE::ColorImage imgClusterAssignmentsRGB (imgClusterAssignments.width(), imgClusterAssignments.height() );
  82. imageToPseudoColor( imgClusterAssignments, imgClusterAssignmentsRGB );
  83. showImage(imgClusterAssignmentsRGB, "cluster Assignments" ) ;
  84. }
  85. //**********************************************
  86. //
  87. // FOR-LOOP OVER UNSEEN IMAGES
  88. //
  89. // EXTRACT FEATURES, CLUSTER THEM, TAKE
  90. // MOST "VALUABLE" CLUSTERS AS NEW
  91. // REPRESENTATIVES IN AN INCREASED CODEBOK
  92. //
  93. //**********************************************
  94. const LabeledSet *testFiles = md["test"];
  95. std::cerr << "start looping over all files" << std::endl;
  96. int imageCnt ( 0 );
  97. LOOP_ALL_S( *testFiles )
  98. {
  99. EACH_INFO( classno, info );
  100. std::string filename = info.img();
  101. NICE::ColorImage orig( filename );
  102. // showImage( orig, "Input" );
  103. NICE::FloatImage noveltyImageBefore;
  104. noveltyImageBefore = featureLearning->evaluateCurrentCodebookByDistance( filename , true /* beforeComputingNewFeatures */ );
  105. //**********************************************
  106. //
  107. // IS THIS IMAGE NOVEL?
  108. //
  109. // IF NOT, GO TO THE NEXT ONE
  110. //
  111. //**********************************************
  112. //TODO currently hard coded, and only stupid averaging of feature novelties for whole image, and hard thresholding!
  113. double meanNovelty ( 0.0 );
  114. for ( uint y = 0 ; y < ( uint ) noveltyImageBefore.height() ; y++ )
  115. {
  116. for ( uint x = 0 ; x < ( uint ) noveltyImageBefore.width(); x++ )
  117. {
  118. meanNovelty += noveltyImageBefore(x,y);
  119. }
  120. }
  121. int imageSize ( noveltyImageBefore.height() * noveltyImageBefore.width() );
  122. meanNovelty /= imageSize;
  123. // double stupidThreshold ( 0.0022 ); // for grid size 5
  124. // double stupidThreshold ( 0.01 ); // for grid size 3
  125. double stupidThreshold = conf->gD ( "featureLearning" , "stupidNoveltyThreshold", 0.0064 );
  126. std::cerr << " NOVELTY SCORE FOR CURRENT IMAGE: " << meanNovelty << " -- threshold: " << stupidThreshold << std::endl;
  127. if ( meanNovelty < stupidThreshold )
  128. {
  129. std::cerr << " --- NOT NOVEL --- " << std::endl << std::endl;
  130. continue;
  131. }
  132. else
  133. {
  134. std::cerr << " --- NOVEL --- " << std::endl;
  135. }
  136. //**********************************************
  137. //
  138. // LEARN NEW FEATURE FOR A NOVEL IMAGE
  139. //
  140. //**********************************************
  141. featureLearning->learnNewFeatures( filename );
  142. //**********************************************
  143. //
  144. // EVALUATE HOW WELL THE CURRENT IMAGE
  145. // CAN BE EXPLAINED AFTER
  146. // COMPUTING A NEW FEATURE
  147. //
  148. // SHOULD WE REPEAT THIS UNTIL THE IMAGE
  149. // IS NOT CLASSIFIED AS "NOVEL" ANYMORE?
  150. //
  151. //**********************************************
  152. NICE::FloatImage noveltyImageAfter;
  153. noveltyImageAfter = featureLearning->evaluateCurrentCodebookByDistance( filename , false /* beforeComputingNewFeatures */ );
  154. NICE::FloatImage noveltyImageDifference ( noveltyImageAfter.width(), noveltyImageAfter.height());
  155. for ( uint y = 0 ; y < ( uint ) noveltyImageAfter.height() ; y++ )
  156. {
  157. for ( uint x = 0 ; x < ( uint ) noveltyImageAfter.width(); x++ )
  158. {
  159. noveltyImageDifference(x,y) = fabs ( noveltyImageBefore(x,y) - noveltyImageAfter(x,y) );
  160. }
  161. }
  162. std::cerr << "min diff: " << noveltyImageDifference.min() << " and max diff: " << noveltyImageDifference.max() << std::endl;
  163. NICE::ColorImage noveltyImageDifferenceRGB (noveltyImageAfter.width(), noveltyImageAfter.height() );
  164. imageToPseudoColor( noveltyImageDifference, noveltyImageDifferenceRGB );
  165. std::vector< std::string > list2;
  166. StringTools::split ( filename, '/', list2 );
  167. std::string destination ( resultdir + NICE::intToString(imageCnt) + "_" + list2.back() + "_4_differenceOfNovelties.ppm");
  168. noveltyImageDifferenceRGB.writePPM( destination );
  169. NICE::ImageT< int > imgClusterAssignmentsBinary;
  170. imgClusterAssignmentsBinary = featureLearning->evaluateCurrentCodebookByAssignments(filename , true, true /* _binaryShowLatestPrototype*/ );
  171. NICE::ImageT< int > imgClusterAssignments;
  172. imgClusterAssignments = featureLearning->evaluateCurrentCodebookByAssignments(filename , true, false /* _binaryShowLatestPrototype*/ );
  173. NICE::ColorImage imgClusterAssignmentsBinaryRGB (imgClusterAssignmentsBinary.width(), imgClusterAssignmentsBinary.height() );
  174. imageToPseudoColor( imgClusterAssignmentsBinary, imgClusterAssignmentsBinaryRGB );
  175. NICE::ColorImage imgClusterAssignmentsRGB (imgClusterAssignments.width(), imgClusterAssignments.height() );
  176. imageToPseudoColor( imgClusterAssignments, imgClusterAssignmentsRGB );
  177. if ( false )
  178. {
  179. showImage(imgClusterAssignmentsBinaryRGB, "cluster Assignments Binary (latest prototype)" ) ;
  180. showImage(imgClusterAssignmentsRGB, "cluster Assignments" ) ;
  181. }
  182. else
  183. {
  184. std::string destination ( resultdir + NICE::intToString(imageCnt) + "_" + list2.back() + "_5_clusterAssignments.ppm");
  185. std::string destinationBinary ( resultdir + NICE::intToString(imageCnt) + "_" + list2.back() + "_6_clusterAssignmentsBinary.ppm");
  186. imgClusterAssignmentsRGB.writePPM( destination );
  187. imgClusterAssignmentsBinaryRGB.writePPM( destinationBinary );
  188. }
  189. imageCnt++;
  190. } //Loop over all test images
  191. return 0;
  192. }