#ifndef RSMARKOVCLUSTER #define RSMARKOVCLUSTER /** * @file RSMarkovCluster.h * @brief ... * @author Björn Fröhlich, Alexander Freytag * @date ??? */ // core - includes #include "core/vector/VectorT.h" #include "core/vector/VVector.h" #include "core/basics/Config.h" #include "core/imagedisplay/ImageDisplay.h" // segmentation - includes #include "segmentation/math/NodeCentricRepMatrix.h" #include "segmentation/RegionSegmentationMethod.h" // std - includes #include #include #include namespace OBJREC { class RSMarkovCluster : public RegionSegmentationMethod { /* Typedefs und Memberklassen */ public: /** * @brief Memberklasse um ein Koordinatenpaar zu repraesentieren. */ class Coord : public std::pair< int, int > { public: //! Standard-Konstruktor Coord() : std::pair() {}; //! Initialisierungs-Konstruktor Coord ( const int y, const int x ) : std::pair ( y, x ) {}; //! Copy-Konstruktor Coord ( Coord const& coord ) : std::pair ( coord ) {}; //! Standard-Destruktor ~Coord() {}; /** * @brief Einfache Methode zum berechnen der PNorm eines Koordinatenpaares. * @param p - Normart * @return p-Norm */ inline double pnorm ( const uint p ) const { return pow ( pow ( abs ( std::pair< int, int >::first ), p ) + pow ( abs ( std::pair< int, int >::second ), p ), ( 1.0 / p ) ); }; /* Operatoren */ //! =+ operator Coord& operator+= ( Coord const& rhs ) { ( *this ).first += rhs.first; ( *this ).second += rhs.second; return ( *this ); }; //! + operator Coord operator+ ( Coord const& rhs ) { Coord tmp ( ( *this ) ); tmp += rhs; return tmp; }; }; private: //! Simpler Datentyp um die Offsets zu speichern. typedef std::vector< RSMarkovCluster::Coord > Offsets; //! Simpler Datentyp zum Speichern der Detours. typedef std::vector< std::vector< std::pair< uint, uint > > > Detours; /* Membermethoden und -variablen */ public: ///////////////////// ///////////////////// ///////////////////// // CONSTRUCTORS / DESTRUCTORS ///////////////////// ///////////////////// ///////////////////// /** * @brief default constructor * @author Alexander Freytag * @date 08-02-2014 ( dd-mm-yyyy ) */ RSMarkovCluster(); //! Standard-Konstruktor RSMarkovCluster ( const NICE::Config* conf ); //! Standard-Destruktor virtual ~RSMarkovCluster(); /** * @brief Setup internal variables and objects used * @author Alexander Freytag * @param conf Config file to specify variable settings * @param s_confSection * @date 08-02-2014 ( dd-mm-yyyy ) */ virtual void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "RSMarkovCluster" ); ///////////////////// ///////////////////// ///////////////////// // SEGMENTATION STUFF ///////////////////// ///////////////////// ////////////////// /* Ueberschriebene Methoden */ /** * @brief Segmentierungsmethode. * @param Image - (Grauwert) Eingabebild * @param Matrix - Segmentierungsmaske */ int segRegions ( const NICE::Image &img, NICE::Matrix &mask ) const; /** * @brief Segmentierungsmethode. * @param ColorImage - (Farbbild) Eingabebild * @param Matrix - Segmentierungsmaske */ int segRegions ( const NICE::ColorImage &cimg, NICE::Matrix &mask ) const; private: int iterations; //! Clusterradius double r; //! Edgeweight Parameter double mu; //! Inflation Parameter double p; //! Chaosthreshold double chaosThreshold; /* */ /** * @brief Vorausberechnung der Offsets */ void precalcOffsets ( Offsets& offsets ) const; /** * @brief Vorausberechnung der Detours */ void precalcDetours ( Detours& detours, const Offsets& offsets ) const; /** * @brief Finder Cluster und markieren derer in der mark Maske. */ int findCluster ( const Offsets& offsets, OBJREC::NodeCentricRepMatrix& L, NICE::Matrix& mark ) const; /** * @brief Errechnen des Indexes eines Pixels anhand seiner Koordinaten. */ inline uint indexOfPixel ( const Coord& yx, const uint xSize ) const; /** * @brief Normalisieren der L Matrix. Dh. alle abgehenenden Kanten werden zu 1 normiert. */ void normalize ( OBJREC::NodeCentricRepMatrix& L ) const; /** * @brief Inflationoperator anwenden. Es gilt: Lout<--inf(Lin) */ void inflation ( const OBJREC::NodeCentricRepMatrix& Lin, OBJREC::NodeCentricRepMatrix& Lout ) const; /** * @brief Expansionoperator anwenden. Es gilt: Lout<--exp(Lin) */ void expansion ( const OBJREC::NodeCentricRepMatrix& Lin, OBJREC::NodeCentricRepMatrix& Lout, const Offsets& offsets, const Detours& detours ) const; /** * @brief Ueberprueft auf negativ NaN und gibt in dem Falle 0.0 zurueck, sonst val. */ inline double checkForNAN ( const double val ) const; /** * @brief Anwenden des Clusterings auf die L1-Matrix. * @note Kovergenzkriterium ist die Veraenderung innerhalb der Matrix zwischen aufeinanderfolgenden Iterationen. */ void runClustering ( const Offsets& offsets, const Detours& detours, OBJREC::NodeCentricRepMatrix& L1 ) const; /** * @brief Initialisierung der MarkovMatrix. Diese Methode ist anwendbar fuer Farb- und Grauwertbilder. */ void initMarkovMatrix ( const uchar* imageData, const uint imageHeight, const uint imageWidth, const uint channelCount, const Offsets& offsets, OBJREC::NodeCentricRepMatrix& L ) const; /** * @brief Berechnung der Kantenstaerke fuer eine gegebene Farb- oder Grauwertdifferenz. */ inline double edgeWeight ( const NICE::Vector& imageValueDiff ) const; /** * @brief Ausgabe der Matrix in eine Datei. VORSICHT: nur fuer sehr kleine Bilder anwenden. */ void printMatrix ( const OBJREC::NodeCentricRepMatrix& L, const Offsets& offsets, const std::string& filename ) const; ///////////////////// INTERFACE PERSISTENT ///////////////////// // interface specific methods for store and restore ///////////////////// INTERFACE PERSISTENT ///////////////////// /** * @brief Load object from external file (stream) * @author Alexander Freytag * @date 08-02-2014 ( dd-mm-yyyy ) */ void restore ( std::istream & is, int format = 0 ); /** * @brief Save object to external file (stream) * @author Alexander Freytag * @date 08-02-2014 ( dd-mm-yyyy ) */ void store ( std::ostream & os, int format = 0 ) const; /** * @brief Clear object * @author Alexander Freytag * @date 08-02-2014 ( dd-mm-yyyy ) */ void clear (); }; } #endif