|
@@ -0,0 +1,230 @@
|
|
|
+
|
|
|
+#include "NoveltyDetectorCodebookLevel.h"
|
|
|
+
|
|
|
+//STL
|
|
|
+#include <iostream>
|
|
|
+
|
|
|
+//core
|
|
|
+#include <core/vector/VectorT.h>
|
|
|
+
|
|
|
+//vislearning
|
|
|
+#include <vislearning/features/localfeatures/LFonHSG.h>
|
|
|
+#include <vislearning/features/localfeatures/LFColorSande.h>
|
|
|
+#include <vislearning/features/localfeatures/LFColorWeijer.h>
|
|
|
+#include <vislearning/features/localfeatures/LFReadCache.h>
|
|
|
+#include <vislearning/features/localfeatures/LFWriteCache.h>
|
|
|
+
|
|
|
+using namespace std;
|
|
|
+using namespace NICE;
|
|
|
+using namespace OBJREC;
|
|
|
+
|
|
|
+ //**********************************************
|
|
|
+ //
|
|
|
+ // PROTECTED METHODS
|
|
|
+ //
|
|
|
+ //**********************************************
|
|
|
+
|
|
|
+
|
|
|
+void NoveltyDetectorCodebookLevel::setFeatureExtractor( const bool & _setForTraining )
|
|
|
+{
|
|
|
+ //be careful with previously allocated memory
|
|
|
+ if (this->featureExtractor != NULL)
|
|
|
+ delete featureExtractor;
|
|
|
+
|
|
|
+ //feature stuff
|
|
|
+ // which OpponentSIFT implementation to use {NICE, VANDESANDE}
|
|
|
+ std::string opSiftImpl;
|
|
|
+ opSiftImpl = this->conf->gS ( "Descriptor", "implementation", "VANDESANDE" );
|
|
|
+ // read features?
|
|
|
+ bool readfeat;
|
|
|
+ readfeat = this->conf->gB ( "Descriptor", "read", true );
|
|
|
+ // write features?
|
|
|
+ bool writefeat;
|
|
|
+ writefeat = this->conf->gB ( "Descriptor", "write", true );
|
|
|
+
|
|
|
+ // Welche Opponentsift Implementierung soll genutzt werden ?
|
|
|
+ LocalFeatureRepresentation *cSIFT = NULL;
|
|
|
+ LocalFeatureRepresentation *writeFeats = NULL;
|
|
|
+ LocalFeatureRepresentation *readFeats = NULL;
|
|
|
+ this->featureExtractor = NULL;
|
|
|
+ if ( opSiftImpl == "NICE" )
|
|
|
+ {
|
|
|
+ if ( _setForTraining )
|
|
|
+ cSIFT = new OBJREC::LFonHSG ( this->conf, "HSGtrain" );
|
|
|
+ else
|
|
|
+ cSIFT = new OBJREC::LFonHSG ( this->conf, "HSGtest" );
|
|
|
+ }
|
|
|
+ else if ( opSiftImpl == "VANDESANDE" )
|
|
|
+ {
|
|
|
+ if ( _setForTraining )
|
|
|
+ cSIFT = new OBJREC::LFColorSande ( this->conf, "LFColorSandeTrain" );
|
|
|
+ else
|
|
|
+ cSIFT = new OBJREC::LFColorSande ( this->conf, "LFColorSandeTest" );
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ fthrow ( Exception, "feattype: %s not yet supported" << opSiftImpl );
|
|
|
+ }
|
|
|
+
|
|
|
+ this->featureExtractor = cSIFT;
|
|
|
+
|
|
|
+ if ( writefeat )
|
|
|
+ {
|
|
|
+ // write the features to a file, if there isn't any to read
|
|
|
+ writeFeats = new LFWriteCache ( this->conf, cSIFT );
|
|
|
+ this->featureExtractor = writeFeats;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( readfeat )
|
|
|
+ {
|
|
|
+ // read the features from a file
|
|
|
+ if ( writefeat )
|
|
|
+ {
|
|
|
+ readFeats = new LFReadCache ( this->conf, writeFeats, -1 );
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ readFeats = new LFReadCache ( this->conf, cSIFT, -1 );
|
|
|
+ }
|
|
|
+ this->featureExtractor = readFeats;
|
|
|
+ }
|
|
|
+
|
|
|
+ //only set feature stuff to NULL, deletion of the underlying object is done in the destructor
|
|
|
+ if ( cSIFT != NULL )
|
|
|
+ cSIFT = NULL;
|
|
|
+ if ( writeFeats != NULL )
|
|
|
+ writeFeats = NULL;
|
|
|
+ if ( readFeats != NULL )
|
|
|
+ readFeats = NULL ;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+bool NoveltyDetectorCodebookLevel::loadInitialCodebook ( )
|
|
|
+{
|
|
|
+ if ( b_loadInitialCodebook )
|
|
|
+ {
|
|
|
+ std::cerr << " INITIAL CODEBOOK ALREADY COMPUTED - RE-USE IT" << std::endl;
|
|
|
+ std::cerr << " // WARNING - WE DO NOT VERIFY WHETHER THIS IS THE CORRECT CODEBOOK FOR THIS TRAINING SET!!!!" << std::endl;
|
|
|
+
|
|
|
+ prototypes->clear();
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ prototypes->read(cacheInitialCodebook);
|
|
|
+ }
|
|
|
+ catch (...)
|
|
|
+ {
|
|
|
+ std::cerr << "Error while loading initial codebook" << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+bool NoveltyDetectorCodebookLevel::writeInitialCodebook ( )
|
|
|
+{
|
|
|
+ if ( b_saveInitialCodebook )
|
|
|
+ {
|
|
|
+ std::cerr << " SAVE INITIAL CODEBOOK " << std::endl;
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ prototypes->write( cacheInitialCodebook );
|
|
|
+ }
|
|
|
+ catch (...)
|
|
|
+ {
|
|
|
+ std::cerr << "Error while saving initial codebook" << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ //**********************************************
|
|
|
+ //
|
|
|
+ // PUBLIC METHODS
|
|
|
+ //
|
|
|
+ //**********************************************
|
|
|
+
|
|
|
+
|
|
|
+NoveltyDetectorCodebookLevel::NoveltyDetectorCodebookLevel ( const Config *_conf,
|
|
|
+ const MultiDataset *_md, const std::string & _section )
|
|
|
+ : NoveltyDetector ( _conf, _section )
|
|
|
+{
|
|
|
+ // define the distance function to be used
|
|
|
+ std::string distFunctionString = conf->gS(section, "distFunction", "euclidian");
|
|
|
+
|
|
|
+
|
|
|
+ //**********************************************
|
|
|
+ //
|
|
|
+ // SET UP VARIABLES AND METHODS
|
|
|
+ // - FEATURE TYPE
|
|
|
+ // - DISTANCE FUNCTION
|
|
|
+ // - ...
|
|
|
+ //
|
|
|
+ //**********************************************
|
|
|
+
|
|
|
+
|
|
|
+ if (distFunctionString.compare("euclidian") == 0)
|
|
|
+ {
|
|
|
+ distFunction = new NICE::EuclidianDistance<double>();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ std::cerr << "Unknown vector distance selected, use euclidian instead" << std::endl;
|
|
|
+ distFunction = new NICE::EuclidianDistance<double>();
|
|
|
+ }
|
|
|
+
|
|
|
+ //feature extraction for comparison against codebook
|
|
|
+ this->featureExtractor = NULL;
|
|
|
+ //feature extraction for unseen images
|
|
|
+ this->setFeatureExtractor( false /* set for training */ );
|
|
|
+
|
|
|
+ this->prototypes = NULL;
|
|
|
+}
|
|
|
+
|
|
|
+NoveltyDetectorCodebookLevel::~NoveltyDetectorCodebookLevel()
|
|
|
+{
|
|
|
+ // clean-up
|
|
|
+ if ( distFunction != NULL )
|
|
|
+ delete distFunction;
|
|
|
+ if ( featureExtractor != NULL )
|
|
|
+ delete featureExtractor;
|
|
|
+ if ( ( ! externalCodebook ) && (prototypes != NULL) )
|
|
|
+ delete prototypes;
|
|
|
+}
|
|
|
+
|
|
|
+void NoveltyDetectorCodebookLevel::setCodebook( NICE::VVector * _prototypes)
|
|
|
+{
|
|
|
+ std::cerr << "aim to set codebook" << std::endl;
|
|
|
+ // if we had no codebook so far, we simply store the pointer and remember, that we use the external one
|
|
|
+ // such that we do not have to delete it lateron
|
|
|
+ if ( this->prototypes == NULL)
|
|
|
+ {
|
|
|
+ std::cerr << "previous codebook is null -- set it as external codebook" << std::endl;
|
|
|
+ this->prototypes = _prototypes;
|
|
|
+ this->externalCodebook = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ std::cerr << "previous codebook is not null - do we want to treat the new one as external?" << std::endl;
|
|
|
+ //in case of an internal codebook, we need to copy the whole thing
|
|
|
+ if ( ! externalCodebook )
|
|
|
+ {
|
|
|
+ *(this->prototypes) = *_prototypes;
|
|
|
+ std::cerr << "new codebook treated as internal codebook" << std::endl;
|
|
|
+ }
|
|
|
+ //if we use a pointer to an external codebook, we simply renew the pointer
|
|
|
+ else
|
|
|
+ {
|
|
|
+ this->prototypes = _prototypes;
|
|
|
+ std::cerr << "new codebook treated as external codebook " << std::endl;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|