/** * @file SemSegNoveltyBinary.h * @brief semantic segmentation using the method from Csurka08 * @author Björn Fröhlich, Alexander Freytag * @date 04/24/2009 */ #ifndef SemSegNoveltyBinaryINCLUDE #define SemSegNoveltyBinaryINCLUDE #include "SemanticSegmentation.h" #include "SemSegTools.h" #include "vislearning/classifier/classifierbase/FeaturePoolClassifier.h" #include "vislearning/classifier/genericClassifierSelection.h" #include "vislearning/features/localfeatures/LocalFeatureColorWeijer.h" #include "vislearning/cbaselib/ClassificationResults.h" #include "segmentation/RegionSegmentationMethod.h" /** @brief pixelwise labeling systems */ namespace OBJREC { class SemSegNoveltyBinary : public SemanticSegmentation { protected: //! boolean whether to reuse segmentation results for single images in different runs bool reuseSegmentation; //! boolean whether to read the initial classifier from a file. If not, training will be performed bool read_classifier; //! boolean whether to save the final classifier or not bool save_classifier; //! The cached Data std::string cache; //! Classifier FeaturePoolClassifier *classifier; VecClassifier *vclassifier; //! feature extraction LocalFeatureColorWeijer *featExtract; //! Configuration File const NICE::Config *conf; //! distance between features for training int trainWsize; //! half of the window size for local features int whs; //! rectangle size for classification, 1 means pixelwise int testWSize; //! name of all classes ClassNames cn; //! low level Segmentation method RegionSegmentationMethod *regionSeg; //! set of forbidden/background classes for the initial training std::set forbidden_classesTrain; //! set of forbidden/background classes for the whole process of learning over time std::set forbidden_classesActiveLearning; //! store the class numbers currently used std::set classesInUse; //! only needed for binary scenarios, index of the positive class int positiveClass; //! obviously, the number of classes used for training (i.e., classesInUse.size() ) int numberOfClasses; //! where to save the resulting images (uncertainty and classification results) std::string resultdir; //! find the maximum uncertainty or not within the whole test set bool findMaximumUncert; //! image with most uncertain region NICE::ColorImage maskedImg; //! for debugging and visualization: show novelty images with and without region segmentation and the most novel region bool visualizeALimages; //! maximum uncertainty over all images, i.e., the novelty score of the most "novel" region of all test images double globalMaxUncert; //! determine whether a "novelty" method computes large scores for novel objects (e.g., variance), or small scores (e.g., min abs mean) bool mostNoveltyWithMaxScores; //! current examples for most uncertain region Examples newTrainExamples; //! contains filenames of images and indices of contained regions, that where already queried, to prevent them from being queried again std::map > queriedRegions; std::pair currentRegionToQuery; //! store the binary classification results from a single run to evaluate them with AUC lateron ClassificationResults resultsOfSingleRun; bool write_results; enum NoveltyMethod{ GPVARIANCE, // novel = large variance GPUNCERTAINTY, //novel = small uncertainty (mean / var) GPMINMEAN, //novel = small mean GPMEANRATIO, //novel = small difference between mean of most plausible class and mean of snd // most plausible class (not useful in binary settings) GPWEIGHTALL, // novel = large weight in alpha vector after updating the model (can be predicted exactly) GPWEIGHTRATIO, // novel = small difference between weights for alpha vectors with assumptions of GT label to be the most // plausible against the second most plausible class RANDOM // query regions randomly }; //! specify how "novelty" shall be computed, e.g., using GP-variance, GP-uncertainty, or predicted weight entries NoveltyMethod noveltyMethod; std::string noveltyMethodString; //! just store the name of our classifier std::string classifierString; inline void computeClassificationResults( const NICE::MultiChannelImageT & feats, NICE::ImageT & segresult, NICE::MultiChannelImageT & probabilities, const int & xsize, const int & ysize, const int & featdim ); void computeNoveltyByRandom( NICE::FloatImage & noveltyImage, const NICE::MultiChannelImageT & feats, NICE::ImageT & segresult, NICE::MultiChannelImageT & probabilities, const int & xsize, const int & ysize, const int & featdim ); void computeNoveltyByVariance( NICE::FloatImage & noveltyImage, const NICE::MultiChannelImageT & feats, NICE::ImageT & segresult, NICE::MultiChannelImageT & probabilities, const int & xsize, const int & ysize, const int & featdim ); void computeNoveltyByGPUncertainty ( NICE::FloatImage & noveltyImage, const NICE::MultiChannelImageT & feats, NICE::ImageT & segresult, NICE::MultiChannelImageT & probabilities, const int & xsize, const int & ysize, const int & featdim ); void computeNoveltyByGPMean ( NICE::FloatImage & noveltyImage, const NICE::MultiChannelImageT & feats, NICE::ImageT & segresult, NICE::MultiChannelImageT & probabilities, const int & xsize, const int & ysize, const int & featdim ); void computeNoveltyByGPMeanRatio ( NICE::FloatImage & noveltyImage, const NICE::MultiChannelImageT & feats, NICE::ImageT & segresult, NICE::MultiChannelImageT & probabilities, const int & xsize, const int & ysize, const int & featdim ); void computeNoveltyByGPWeightAll ( NICE::FloatImage & noveltyImage, const NICE::MultiChannelImageT & feats, NICE::ImageT & segresult, NICE::MultiChannelImageT & probabilities, const int & xsize, const int & ysize, const int & featdim ); void computeNoveltyByGPWeightRatio ( NICE::FloatImage & noveltyImage, const NICE::MultiChannelImageT & feats, NICE::ImageT & segresult, NICE::MultiChannelImageT & probabilities, const int & xsize, const int & ysize, const int & featdim ); public: /** constructor * @param conf needs a configfile * @param md and a MultiDataset (contains images and other things) */ SemSegNoveltyBinary ( const NICE::Config *conf, const MultiDataset *md ); /** simple destructor */ virtual ~SemSegNoveltyBinary(); /** The trainingstep * @param md and a MultiDataset (contains images and other things) */ void train ( const MultiDataset *md ); /** The main procedure. Input: Image, Output: Segmented Image with pixelwise labeles and the probabilities * @param ce image data * @param segresult result of the semantic segmentation with a label for each pixel * @param probabilities multi-channel image with one channel for each class and corresponding probabilities for each pixel */ void semanticseg ( CachedExample *ce, NICE::ImageT & segresult, NICE::MultiChannelImageT & probabilities ); void semanticseg ( CachedExample *ce, NICE::MultiChannelImageT & segresult, NICE::MultiChannelImage3DT & probabilities ) {} /** * @brief visualize a specific region in the original image * * @param img input image * @param regions map of the regions * @param region visualize this region * @param outimage result * @return void **/ void visualizeRegion(const NICE::ColorImage &img, const NICE::Matrix ®ions, int region, NICE::ColorImage &outimage); /** * @brief Add a new example to the known training data * * @param newExample (NICE::Vector) the feature vector of the new examples * @param newClassNo (int) the corresponding GT class number * @return void **/ void addNewExample(const NICE::Vector & newExample, const int & newClassNo); /** * @brief Add those examples, which belong to the most novel region seen so far * * @return void **/ virtual void addNovelExamples(); /** * @brief Get a pointer to the examples extracted from the most novel region seen so far * * @return Examples * **/ virtual const Examples * getNovelExamples() const; /** * @brief Compute AUC scores from the results of the images computed so far * * @return double **/ double getAUCPerformance() const; }; } //namespace #endif