#ifndef VMAP_H #define VMAP_H #include "pt2i.h" #include "strucel.h" using namespace std; /** * @class VMap vmap.h * \brief Vector map. * \author {P. Even} */ class VMap { public: /** Gradient extraction method : Sobel with 3x3 kernel. */ static const int TYPE_SOBEL_3X3; /** Gradient extraction method : Sobel with 5x5 kernel. */ static const int TYPE_SOBEL_5X5; /** Gradient extraction method : Morphological top hat (I - E(I)). */ static const int TYPE_TOP_HAT; /** Gradient extraction method : Morphological black hat (D(I) - I). */ static const int TYPE_BLACK_HAT; /** Gradient extraction method : Morphological gradient (D(I) - E(I)). */ static const int TYPE_MORPHO; /** Gradient extraction method : Morphological directional top hat. */ static const int TYPE_FULL_TOP_HAT; /** Gradient extraction method : Morphological directional black hat. */ static const int TYPE_FULL_BLACK_HAT; /** Gradient extraction method : Morphological directional gradient. */ static const int TYPE_FULL_MORPHO; /** * \brief Creates a gradient map from scalar data. * @param width Map width. * @param height Map height. * @param data Scalar data array. * @param type Gradient extraction method (default is Soble with 3x3 kernel). */ VMap (int width, int height, int *data, int type = 0); /** * \brief Creates a gradient map from scalar data. * @param width Map width. * @param height Map height. * @param data Scalar data bi-dimensional array. */ VMap (int width, int height, int **data, int type = 0); /** * \brief Deletes the vector map. */ ~VMap (); /** * \brief Returns the map width. */ inline int getWidth () const { return width; } /** * \brief Returns the map height. */ inline int getHeight () const { return height; } /** * \brief Returns the maximal value between map width or height. */ inline int getHeightWidthMax () const { return (height > width ? height : width); } /** * \brief Checks whether the given point lies within the map bounds. * @param i Column number. * @param j Line number. */ inline bool contains (int i, int j) { return (i >= 0 && i < width && j >= 0 && j < height); } /** * \brief Returns the vector at point (i,j). * @param i Column number. * @param j Line number. */ Vr2i getValue (int i, int j) const { return (map[j * width + i]); } /** * \brief Returns the vector at given point. * @param p Point position. */ Vr2i getValue (Pt2i p) const { return (map[p.y () * width + p.x ()]); } /** * \brief Returns the squared norm of the vector magnitude at point (i,j). * @param i Column number. * @param j Line number. */ int sqNorm (int i, int j) const; /** * \brief Returns the squared norm of the vector magnitude at given point. * @param p Point position. */ int sqNorm (Pt2i p) const; /** * \brief Returns the comparable norm of the vector magnitude at point (i,j). * @param i Column number. * @param j Line number. */ inline int magn (int i, int j) const { return (imap[j * width + i]); } /** * \brief Returns the comparable norm of the vector magnitude at given point. * @param p Point position. */ inline int magn (Pt2i p) const { return (imap[p.y () * width + p.x ()]); } /** * \brief Returns the index of the largest vector at given positions. * First and last points of the list are not accepted. * A gradient minimal threshold is set for the test. * Returns -1 if no max is found. * @param pix List of points. */ int largestIn (const vector<Pt2i> &pix) const; /** * Keeps elements that are not already selected (in the mask array). * Returns the number of remaining elements in the selection. * @param pix Input array of scanned points. * @param n Initial size of the selection of points. * @param ind Selection of points. */ int keepFreeElementsIn (const vector<Pt2i> &pix, int n, int *ind) const; /** * Keeps elements that are oriented along a reference vector * in a selection of points. * Returns the number of remaining elements in the selection. * @param pix Input array of scanned points. * @param ref The reference vector. * @param n Initial size of the selection of points. * @param ind Selection of points. */ int keepOrientedElementsIn (const vector<Pt2i> &pix, const Vr2i &ref, int n, int *ind) const; /** * Keeps elements with gradient value near a reference vector * in a selection of points. * Returns the number of remaining elements in the selection. * @param pix Input array of scanned points. * @param ref The reference vector. * @param n Initial size of the selection of points. * @param ind Selection of points. */ int keepDirectedElementsIn (const vector<Pt2i> &pix, const Vr2i &ref, int n, int *ind) const; /** * \brief Gets filtered and sorted local gradient maxima. * Local max already used are pruned. * Returns the count of found gradient maxima. * @param lmax Local max index array. * @param pix Provided points. */ int localMax (int *lmax, const vector<Pt2i> &pix) const; /** * \brief Gets filtered and sorted local oriented gradient maxima. * Local maxima are filtered according to the gradient direction and sorted. * Returns the count of found gradient maxima. * @param lmax Local max index array. * @param pix Provided points. * @param gref Gradient vector reference. */ int localMax (int *lmax, const vector<Pt2i> &pix, const Vr2i &gref) const; /** * \brief Returns the gradient threshold value used for maxima detection. */ inline int getGradientThreshold () const { return (gradientThreshold); } /** * \brief Increments the gradient threshold value used for maxima detection. */ inline void incGradientThreshold (int inc) { gradientThreshold += inc; if (gradientThreshold < 0) gradientThreshold = 0; if (gradientThreshold > 255) gradientThreshold = 255; gmagThreshold = gradientThreshold; if (gtype <= TYPE_SOBEL_5X5) gmagThreshold *= gradientThreshold; } /** * \brief Switches the direction constraint for local maxima selection. */ inline void switchOrientationConstraint () { orientedGradient = ! orientedGradient; } /** * \brief Clears the occupancy mask. */ void clearMask (); /** * \brief Adds positions to the occupancy mask. * @param pts Vector of points. */ void setMask (const vector<Pt2i> &pts); /** * \brief Sets mask activation on or off * @param status Required activation status. */ inline void setMasking (bool status) { masking = status; } /** * \brief Sets mask activation on or off * @param status Required activation status. */ inline bool isFree (const Pt2i &pt) const { return (! mask[pt.y () * width + pt.x ()]); } private: /** Default value for near angular deviation tests. */ static const int NEAR_SQ_ANGLE; /** Effective value for the angular deviation test. */ int angleThreshold; /** Default threshold value for the gradient selection. */ static const int DEFAULT_GRADIENT_THRESHOLD; /** Image width. */ int width; /** Image height. */ int height; /** Gradient type. */ int gtype; /** Vector map. */ Vr2i *map; /** Magnitude map (squarred norm or morphologicalgradient). */ int *imap; /** Occupancy mask. */ bool *mask; /** Flag indicating whether the occupancy mask is in use. */ bool masking; /** Standardized gradient threshold for highest value detection. */ int gradientThreshold; /** Gradient magnitude threshold for highest value detection. */ int gmagThreshold; /** Direction constraint for local gradient maxima. */ bool orientedGradient; /** * \brief Builds the vector map as a gradient map from provided data. * Uses a Sobel 3x3 kernel. * @param data Initial scalar data. */ void buildGradientMap (int *data); /** * \brief Builds the vector map as a gradient map from provided data. * Uses a Sobel 3x3 kernel. * @param data Initial bi-dimensional scalar data. */ void buildGradientMap (int **data); /** * \brief Builds the vector map as a gradient map from provided data. * Uses a Sobel 5x5 kernel. * @param data Initial scalar data. */ void buildSobel5x5Map (int *data); /** * \brief Builds the vector map as a gradient map from provided data. * Uses a Sobel 5x5 kernel. * @param data Initial bi-dimensional scalar data. */ void buildSobel5x5Map (int **data); /** * \brief Searches local gradient maxima values. * Returns the count of local maxima found. * @param lmax Local max index array. * @param n Count of input values. * @param in Array of input values. */ int searchLocalMax (int *lmax, int n, int *in) const; /** * \brief Sorts the candidates array by highest magnitude. * @param lmax Local max index array. * @param n Size of index array. * @param val Input values. */ void sortMax (int *lmax, int n, int *val) const; }; #endif