testFeatureLearning.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  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. //
  25. #include "vislearning/noveltyDetection/NDCodebookLevelImagePooling.h"
  26. using namespace std;
  27. using namespace NICE;
  28. using namespace OBJREC;
  29. /**
  30. test feature learning routines
  31. */
  32. int main( int argc, char **argv )
  33. {
  34. #ifndef __clang__
  35. #ifndef __llvm__
  36. std::set_terminate( __gnu_cxx::__verbose_terminate_handler );
  37. #endif
  38. #endif
  39. Config * conf = new Config ( argc, argv );
  40. bool showTrainingImages = conf->gB( "featureLearning", "showTrainingImages", false );
  41. bool showTestImages = conf->gB( "featureLearning", "showTestImages", false );
  42. bool showResults = conf->gB( "featureLearning", "showResults", false );
  43. ResourceStatistics rs;
  44. std::string resultdir;
  45. resultdir = conf->gS( "featureLearning", "resultdir", "/tmp/");
  46. NICE::ImageT<int> noveltyScale ( 20, 100 );
  47. for (int j = 0; j < 100; j++)
  48. {
  49. for (int i = 0; i < 20; i++)
  50. noveltyScale(i,j) = 99-j;
  51. }
  52. NICE::ColorImage noveltyScaleRGB (noveltyScale.width(), noveltyScale.height() );
  53. imageToPseudoColor( noveltyScale, noveltyScaleRGB );
  54. std::string destinationNoveltyScale ( resultdir + "_" + "_noveltyScale.ppm");
  55. noveltyScaleRGB.writePPM( destinationNoveltyScale );
  56. //**********************************************
  57. //
  58. // READ INITIAL TRAINING SET TO COMPUTE
  59. // AN INITIAL CODEBOOK
  60. //
  61. //**********************************************
  62. std::cerr << " READ INITIAL TRAINING SET TO COMPUTE AN INITIAL CODEBOOK" << std::endl;
  63. MultiDataset md( conf );
  64. const LabeledSet *trainFiles = md["train"];
  65. //**********************************************
  66. //
  67. // SET UP THE FEATURE LEARNING ALGO
  68. //
  69. //**********************************************
  70. OBJREC::FeatureLearningGeneric * featureLearning;
  71. std::string featureLearningMethod = conf->gS( "featureLearning", "featureLearningMethod", "clusterBased" );
  72. if (featureLearningMethod.compare("clusterBased") == 0)
  73. {
  74. featureLearning = new OBJREC::FeatureLearningClusterBased( conf, &md );
  75. }
  76. else if (featureLearningMethod.compare("regionBased") == 0)
  77. {
  78. featureLearning = new OBJREC::FeatureLearningRegionBased( conf, &md );
  79. }
  80. else
  81. {
  82. std::cerr << "Unknown feature learning algorithm selected, use cluster based instead" << std::endl;
  83. featureLearning = new OBJREC::FeatureLearningClusterBased( conf, &md );
  84. }
  85. //**********************************************
  86. //
  87. // SET UP THE NOVELTY DECTION ALGO
  88. //
  89. //**********************************************
  90. OBJREC::NDCodebookLevelImagePooling * novDetector;
  91. novDetector = new OBJREC::NDCodebookLevelImagePooling( conf, &md, "featureLearning" );
  92. //evaluate how well the training images are covered with our initial codebook
  93. //that is, compute these nice "novelty maps" per feature
  94. //NOTE we skip this currently
  95. LOOP_ALL_S( *trainFiles )
  96. {
  97. EACH_INFO( classno, info );
  98. std::string filename = info.img();
  99. //
  100. // featureLearning->evaluateCurrentCodebook( filename , true /* beforeComputingNewFeatures */);
  101. NICE::ImageT< int > imgClusterAssignments;
  102. imgClusterAssignments = featureLearning->evaluateCurrentCodebookByAssignments(filename , false /* beforeComputingNewFeatures */, false /* _binaryShowLatestPrototype*/ );
  103. std::cerr << "now do image To pseude color and show the initial cluster assignments" << std::endl;
  104. NICE::ColorImage imgClusterAssignmentsRGB (imgClusterAssignments.width(), imgClusterAssignments.height() );
  105. imageToPseudoColor( imgClusterAssignments, imgClusterAssignmentsRGB );
  106. if ( showResults )
  107. showImage(imgClusterAssignmentsRGB, "cluster Assignments" ) ;
  108. else
  109. {
  110. std::vector< std::string > list2;
  111. StringTools::split ( filename, '/', list2 );
  112. std::string destination ( resultdir + NICE::intToString(0) + "_" + list2.back() + "_00_initialClusterAssignments.ppm");
  113. imgClusterAssignmentsRGB.writePPM( destination );
  114. }
  115. }
  116. //**********************************************
  117. //
  118. // EVALUATE INITIAL CLUSTER
  119. //
  120. // COMPUTE A NICE CONFUSION MATRIX
  121. // FOR OUR INITIAL CODEBOOK
  122. //
  123. //**********************************************
  124. NICE::Matrix confusionMatInitial;
  125. featureLearning->evaluateCurrentCodebookByConfusionMatrix( confusionMatInitial );
  126. std::cerr << "initial Confusion matrix: " << std::endl << confusionMatInitial << std::endl;
  127. //set the initially computed codebook to the novelty detection mechanism
  128. //TODO this should be done, but currently we do not care about
  129. // novDetector->setCodebook( featureLearning->getCurrentCodebook() );
  130. //**********************************************
  131. //
  132. // FOR-LOOP OVER UNSEEN IMAGES
  133. //
  134. // EXTRACT FEATURES, CLUSTER THEM, TAKE
  135. // MOST "VALUABLE" CLUSTERS AS NEW
  136. // REPRESENTATIVES IN AN INCREASED CODEBOK
  137. //
  138. //**********************************************
  139. const LabeledSet *testFiles = md["test"];
  140. std::cerr << "start looping over all files" << std::endl;
  141. int imageCnt ( 0 );
  142. LOOP_ALL_S( *testFiles )
  143. {
  144. EACH_INFO( classno, info );
  145. std::string filename = info.img();
  146. NICE::ColorImage orig( filename );
  147. NICE::ImageT< int > imgClusterAssignments;
  148. imgClusterAssignments = featureLearning->evaluateCurrentCodebookByAssignments(filename , false /* beforeComputingNewFeatures */, false /* _binaryShowLatestPrototype*/ );
  149. NICE::ColorImage imgClusterAssignmentsRGB (imgClusterAssignments.width(), imgClusterAssignments.height() );
  150. imageToPseudoColor( imgClusterAssignments, imgClusterAssignmentsRGB );
  151. NICE::FloatImage noveltyImageBefore;
  152. noveltyImageBefore = featureLearning->evaluateCurrentCodebookByDistance( filename , true /* beforeComputingNewFeatures */ );
  153. NICE::ColorImage noveltyImageBeforeRGB (noveltyImageBefore.width(), noveltyImageBefore.height() );
  154. imageToPseudoColor( noveltyImageBefore, noveltyImageBeforeRGB );
  155. if ( showResults )
  156. showImage(imgClusterAssignmentsRGB, "cluster Assignments" ) ;
  157. else
  158. {
  159. std::vector< std::string > list2;
  160. StringTools::split ( filename, '/', list2 );
  161. std::string destination ( resultdir + NICE::intToString(0) + "_" + list2.back() + "_00_initialClusterAssignments.ppm");
  162. imgClusterAssignmentsRGB.writePPM( destination );
  163. std::string destinationNovelty ( resultdir + NICE::intToString(0) + "_" + list2.back() + "_01_initialClusterDistances.ppm");
  164. noveltyImageBeforeRGB.writePPM( destinationNovelty );
  165. }
  166. //**********************************************
  167. //
  168. // IS THIS IMAGE NOVEL?
  169. //
  170. // IF NOT, GO TO THE NEXT ONE
  171. //
  172. //**********************************************
  173. bool b_isImageNovel ( novDetector->evaluateNoveltyOfImage( noveltyImageBefore ) );
  174. if ( ! b_isImageNovel )
  175. {
  176. std::cerr << " --- NOT NOVEL --- " << std::endl << std::endl;
  177. continue;
  178. }
  179. else
  180. {
  181. std::cerr << " --- NOVEL --- " << std::endl;
  182. }
  183. while ( b_isImageNovel )
  184. {
  185. //**********************************************
  186. //
  187. // LEARN NEW FEATURE FOR A NOVEL IMAGE
  188. //
  189. //**********************************************
  190. featureLearning->learnNewFeatures( filename );
  191. //and update the codebook pointer within our novelty detection algorithm
  192. //TODO this should be done, but currently we do not care about
  193. // novDetector->setCodebook( featureLearning->getCurrentCodebook() );
  194. //**********************************************
  195. //
  196. // EVALUATE HOW WELL THE CURRENT IMAGE
  197. // CAN BE EXPLAINED AFTER
  198. // COMPUTING A NEW FEATURE
  199. //
  200. // SHOULD WE REPEAT THIS UNTIL THE IMAGE
  201. // IS NOT CLASSIFIED AS "NOVEL" ANYMORE?
  202. //
  203. //**********************************************
  204. NICE::FloatImage noveltyImageAfter;
  205. noveltyImageAfter = featureLearning->evaluateCurrentCodebookByDistance( filename , false /* beforeComputingNewFeatures */ );
  206. NICE::FloatImage noveltyImageDifference ( noveltyImageAfter.width(), noveltyImageAfter.height());
  207. for ( uint y = 0 ; y < ( uint ) noveltyImageAfter.height() ; y++ )
  208. {
  209. for ( uint x = 0 ; x < ( uint ) noveltyImageAfter.width(); x++ )
  210. {
  211. noveltyImageDifference(x,y) = fabs ( noveltyImageBefore(x,y) - noveltyImageAfter(x,y) );
  212. }
  213. }
  214. std::cerr << "min diff: " << noveltyImageDifference.min() << " and max diff: " << noveltyImageDifference.max() << std::endl;
  215. NICE::ColorImage noveltyImageDifferenceRGB (noveltyImageAfter.width(), noveltyImageAfter.height() );
  216. imageToPseudoColor( noveltyImageDifference, noveltyImageDifferenceRGB );
  217. std::vector< std::string > list2;
  218. StringTools::split ( filename, '/', list2 );
  219. if ( showResults )
  220. {
  221. showImage( noveltyImageDifferenceRGB, "Difference of novelty images" );
  222. }
  223. else
  224. {
  225. std::string destination ( resultdir + NICE::intToString(imageCnt) + "_" + list2.back() + "_02_initialLoopClusterAssignments.ppm");
  226. imgClusterAssignmentsRGB.writePPM( destination );
  227. std::string destinationNoveltyDifference ( resultdir + NICE::intToString(imageCnt) + "_" + list2.back() + "_03_noveltyDifferences.ppm");
  228. noveltyImageDifferenceRGB.writePPM( destinationNoveltyDifference );
  229. }
  230. NICE::ImageT< int > imgClusterAssignmentsBinary;
  231. imgClusterAssignmentsBinary = featureLearning->evaluateCurrentCodebookByAssignments(filename , true, true /* _binaryShowLatestPrototype*/ );
  232. NICE::ImageT< int > imgClusterAssignments;
  233. imgClusterAssignments = featureLearning->evaluateCurrentCodebookByAssignments(filename , true, false /* _binaryShowLatestPrototype*/ );
  234. NICE::ColorImage imgClusterAssignmentsBinaryRGB (imgClusterAssignmentsBinary.width(), imgClusterAssignmentsBinary.height() );
  235. imageToPseudoColor( imgClusterAssignmentsBinary, imgClusterAssignmentsBinaryRGB );
  236. NICE::ColorImage imgClusterAssignmentsRGB (imgClusterAssignments.width(), imgClusterAssignments.height() );
  237. imageToPseudoColor( imgClusterAssignments, imgClusterAssignmentsRGB );
  238. if ( showResults )
  239. {
  240. showImage(imgClusterAssignmentsBinaryRGB, "cluster Assignments Binary (latest prototype)" ) ;
  241. showImage(imgClusterAssignmentsRGB, "cluster Assignments" ) ;
  242. }
  243. else
  244. {
  245. std::string destination ( resultdir + NICE::intToString(imageCnt) + "_" + list2.back() + "_5_clusterAssignments.ppm");
  246. std::string destinationBinary ( resultdir + NICE::intToString(imageCnt) + "_" + list2.back() + "_6_clusterAssignmentsBinary.ppm");
  247. imgClusterAssignmentsRGB.writePPM( destination );
  248. imgClusterAssignmentsBinaryRGB.writePPM( destinationBinary );
  249. }
  250. //check, whether the image will still be seen as novel or not
  251. // i.e., are we able to "explain" the image with the lately computed codebook entry?
  252. b_isImageNovel = novDetector->evaluateNoveltyOfImage( noveltyImageAfter ) ;
  253. if ( ! b_isImageNovel )
  254. {
  255. std::cerr << " --- NOT NOVEL ANYMORE --- " << std::endl << std::endl;
  256. }
  257. else
  258. {
  259. std::cerr << " --- STILL NOVEL --- " << std::endl;
  260. noveltyImageBefore = noveltyImageAfter;
  261. }
  262. //artifial break for the moment
  263. break;
  264. }
  265. imageCnt++;
  266. } //Loop over all test images
  267. //don't waste memory
  268. std::cerr << "don't waste memory - cleaning up" << std::endl;
  269. // if (trainFiles != NULL)
  270. // delete trainFiles;
  271. if (featureLearning != NULL)
  272. delete featureLearning;
  273. if (novDetector != NULL)
  274. delete novDetector;
  275. if (conf != NULL)
  276. delete conf;
  277. return 0;
  278. }