LCOV - code coverage report
Current view: directory - alg - gdal_simplesurf.h (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 5 0 0.0 %
Date: 2012-12-26 Functions: 1 0 0.0 %

       1                 : /******************************************************************************
       2                 :  * Project:  GDAL
       3                 :  * Purpose:  Correlator
       4                 :  * Author:   Andrew Migal, migal.drew@gmail.com
       5                 :  *
       6                 :  ******************************************************************************
       7                 :  * Copyright (c) 2012, Andrew Migal
       8                 :  *
       9                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      10                 :  * copy of this software and associated documentation files (the "Software"),
      11                 :  * to deal in the Software without restriction, including without limitation
      12                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      13                 :  * and/or sell copies of the Software, and to permit persons to whom the
      14                 :  * Software is furnished to do so, subject to the following conditions:
      15                 :  *
      16                 :  * The above copyright notice and this permission notice shall be included
      17                 :  * in all copies or substantial portions of the Software.
      18                 :  *
      19                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      20                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      21                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      22                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      23                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      24                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      25                 :  * DEALINGS IN THE SOFTWARE.
      26                 :  ****************************************************************************/
      27                 : 
      28                 : /**
      29                 :  * @file
      30                 :  * @author Andrew Migal migal.drew@gmail.com
      31                 :  * @brief Class for searching corresponding points on images.
      32                 :  */
      33                 : 
      34                 : #ifndef GDALSIMPLESURF_H_
      35                 : #define GDALSIMPLESURF_H_
      36                 : 
      37                 : #include "gdal_priv.h"
      38                 : #include "cpl_conv.h"
      39                 : #include <list>
      40                 : 
      41                 : /**
      42                 :  * @brief Class of "feature point" in raster. Used by SURF-based algorithm.
      43                 :  *
      44                 :  * @details This point presents coordinates of distinctive pixel in image.
      45                 :  * In computer vision, feature points - the most "strong" and "unique"
      46                 :  * pixels (or areas) in picture, which can be distinguished from others.
      47                 :  * For more details, see FAST corner detector, SIFT, SURF and similar algorithms.
      48                 :  */
      49                 : class GDALFeaturePoint
      50                 : {
      51                 : public:
      52                 :     /**
      53                 :      * Standard constructor. Initializes all parameters with negative numbers
      54                 :      * and allocates memory for descriptor.
      55                 :      */
      56                 :     GDALFeaturePoint();
      57                 : 
      58                 :     /**
      59                 :      * Copy constructor
      60                 :      * @param fp Copied instance of GDALFeaturePoint class
      61                 :      */
      62                 :     GDALFeaturePoint(const GDALFeaturePoint& fp);
      63                 : 
      64                 :     /**
      65                 :      * Create instance of GDALFeaturePoint class
      66                 :      *
      67                 :      * @param nX X-coordinate (pixel)
      68                 :      * @param nY Y-coordinate (line)
      69                 :      * @param nScale Scale which contains this point (2, 4, 8, 16 and so on)
      70                 :      * @param nRadius Half of the side of descriptor area
      71                 :      * @param nSign Sign of Hessian determinant for this point
      72                 :      *
      73                 :      * @note This constructor normally is invoked by SURF-based algorithm,
      74                 :      * which provides all necessary parameters.
      75                 :      */
      76                 :     GDALFeaturePoint(int nX, int nY, int nScale, int nRadius, int nSign);
      77                 :     virtual ~GDALFeaturePoint();
      78                 : 
      79                 :     GDALFeaturePoint& operator=(const GDALFeaturePoint& point);
      80                 : 
      81                 :     /**
      82                 :      * Provide access to point's descriptor.
      83                 :      *
      84                 :      * @param nIndex Position of descriptor's value.
      85                 :      * nIndex should be within range from 0 to DESC_SIZE (in current version - 64)
      86                 :      *
      87                 :      * @return Reference to value of descriptor in 'nIndex' position.
      88                 :      * If index is out of range then behaviour is undefined.
      89                 :      */
      90                 :     double& operator[](int nIndex);
      91                 : 
      92                 :     // Descriptor length
      93                 :     static const int DESC_SIZE = 64;
      94                 : 
      95                 :     /**
      96                 :      * Fetch X-coordinate (pixel) of point
      97                 :      *
      98                 :      * @return X-coordinate in pixels
      99                 :      */
     100                 :     int GetX();
     101                 : 
     102                 :     /**
     103                 :      * Set X coordinate of point
     104                 :      *
     105                 :      * @param nX X coordinate in pixels
     106                 :      */
     107                 :     void SetX(int nX);
     108                 : 
     109                 :     /**
     110                 :      * Fetch Y-coordinate (line) of point.
     111                 :      *
     112                 :      * @return Y-coordinate in pixels.
     113                 :      */
     114                 :     int  GetY();
     115                 : 
     116                 :     /**
     117                 :      * Set Y coordinate of point.
     118                 :      *
     119                 :      * @param nY Y coordinate in pixels.
     120                 :      */
     121                 :     void SetY(int nY);
     122                 : 
     123                 :     /**
     124                 :      * Fetch scale of point.
     125                 :      *
     126                 :      * @return Scale for this point.
     127                 :      */
     128                 :     int  GetScale();
     129                 : 
     130                 :     /**
     131                 :      * Set scale of point.
     132                 :      *
     133                 :      * @param nScale Scale for this point.
     134                 :      */
     135                 :     void SetScale(int nScale);
     136                 : 
     137                 :     /**
     138                 :      * Fetch radius of point.
     139                 :      *
     140                 :      * @return Radius for this point.
     141                 :      */
     142                 :     int  GetRadius();
     143                 : 
     144                 :     /**
     145                 :      * Set radius of point.
     146                 :      *
     147                 :      * @param nRadius Radius for this point.
     148                 :      */
     149                 :     void SetRadius(int nRadius);
     150                 : 
     151                 :     /**
     152                 :      * Fetch sign of Hessian determinant of point.
     153                 :      *
     154                 :      * @return Sign for this point.
     155                 :      */
     156                 :     int  GetSign();
     157                 : 
     158                 :     /**
     159                 :      * Set sign of point.
     160                 :      *
     161                 :      * @param nSign Sign of Hessian determinant for this point.
     162                 :      */
     163                 :     void SetSign(int nSign);
     164                 : 
     165                 : private:
     166                 :     // Coordinates of point in image
     167                 :     int nX;
     168                 :     int nY;
     169                 :     // --------------------
     170                 :     int nScale;
     171                 :     int nRadius;
     172                 :     int nSign;
     173                 :     // Descriptor array
     174                 :     double *padfDescriptor;
     175                 : };
     176                 : 
     177                 : /**
     178                 :  * @author Andrew Migal migal.drew@gmail.com
     179                 :  * @brief Integral image class (summed area table).
     180                 :  * @details Integral image is a table for fast computing the sum of
     181                 :  * values in rectangular subarea. In more detail, for 2-dimensional array
     182                 :  * of numbers this class provides capabilty to get sum of values in
     183                 :  * rectangular arbitrary area with any size in constant time.
     184                 :  * Integral image is constructed from grayscale picture.
     185                 :  */
     186                 : class GDALIntegralImage
     187                 : {
     188                 : public:
     189                 :     GDALIntegralImage();
     190                 :     virtual ~GDALIntegralImage();
     191                 : 
     192                 :     /**
     193                 :      * Compute integral image for specified array. Result is stored internally.
     194                 :      *
     195                 :      * @param padfImg Pointer to 2-dimensional array of values
     196                 :      * @param nHeight Number of rows in array
     197                 :      * @param nWidth Number of columns in array
     198                 :      */
     199                 :     void Initialize(const double **padfImg, int nHeight, int nWidth);
     200                 : 
     201                 :     /**
     202                 :      * Fetch value of specified position in integral image.
     203                 :      *
     204                 :      * @param nRow Row of this position
     205                 :      * @param nCol Column of this position
     206                 :      *
     207                 :      * @return Value in specified position or zero if parameters are out of range.
     208                 :      */
     209                 :     double GetValue(int nRow, int nCol);
     210                 : 
     211                 :     /**
     212                 :      * Get sum of values in specified rectangular grid. Rectangle is constructed
     213                 :      * from left top point.
     214                 :      *
     215                 :      * @param nRow Row of left top point of rectangle
     216                 :      * @param nCol Column of left top point of rectangle
     217                 :      * @param nWidth Width of rectangular area (number of columns)
     218                 :      * @param nHeight Heigth of rectangular area (number of rows)
     219                 :      *
     220                 :      * @return Sum of values in specified grid.
     221                 :      */
     222                 :     double GetRectangleSum(int nRow, int nCol, int nWidth, int nHeight);
     223                 : 
     224                 :     /**
     225                 :      * Get value of horizontal Haar wavelet in specified square grid.
     226                 :      *
     227                 :      * @param nRow Row of left top point of square
     228                 :      * @param nCol Column of left top point of square
     229                 :      * @param nSize Side of the square
     230                 :      *
     231                 :      * @return Value of horizontal Haar wavelet in specified square grid.
     232                 :      */
     233                 :     double HaarWavelet_X(int nRow, int nCol, int nSize);
     234                 : 
     235                 :     /**
     236                 :      * Get value of vertical Haar wavelet in specified square grid.
     237                 :      *
     238                 :      * @param nRow Row of left top point of square
     239                 :      * @param nCol Column of left top point of square
     240                 :      * @param nSize Side of the square
     241                 :      *
     242                 :      * @return Value of vertical Haar wavelet in specified square grid.
     243                 :      */
     244                 :     double HaarWavelet_Y(int nRow, int nCol, int nSize);
     245                 : 
     246                 :     /**
     247                 :      * Fetch height of integral image.
     248                 :      *
     249                 :      * @return Height of integral image (number of rows).
     250                 :      */
     251                 :     int GetHeight();
     252                 : 
     253                 :     /**
     254                 :      * Fetch width of integral image.
     255                 :      *
     256                 :      * @return Width of integral image (number of columns).
     257                 :      */
     258                 :     int GetWidth();
     259                 : 
     260                 : private:
     261                 :     double **pMatrix;
     262                 :     int nWidth;
     263                 :     int nHeight;
     264                 : };
     265                 : 
     266                 : /**
     267                 :  * @author Andrew Migal migal.drew@gmail.com
     268                 :  * @brief Class for computation and storage of Hessian values in SURF-based algorithm.
     269                 :  *
     270                 :  * @details SURF-based algorithm normally uses this class for searching
     271                 :  * feature points on raster images. Class also contains traces of Hessian matrices
     272                 :  * to provide fast computations.
     273                 :  */
     274                 : class GDALOctaveLayer
     275                 : {
     276                 : public:
     277                 :     GDALOctaveLayer();
     278                 : 
     279                 :     /**
     280                 :      * Create instance with provided parameters.
     281                 :      *
     282                 :      * @param nOctave Number of octave which contains this layer
     283                 :      * @param nInterval Number of position in octave
     284                 :      *
     285                 :      * @note Normally constructor is invoked only by SURF-based algorithm.
     286                 :      */
     287                 :     GDALOctaveLayer(int nOctave, int nInterval);
     288                 :     virtual ~GDALOctaveLayer();
     289                 : 
     290                 :     /**
     291                 :      * Perform calculation of Hessian determinats and their signs
     292                 :      * for specified integral image. Result is stored internally.
     293                 :      *
     294                 :      * @param poImg Integral image object, which provides all necessary
     295                 :      * data for computation
     296                 :      *
     297                 :      * @note Normally method is invoked only by SURF-based algorithm.
     298                 :      */
     299                 :     void ComputeLayer(GDALIntegralImage *poImg);
     300                 : 
     301                 :     /**
     302                 :      * Octave which contains this layer (1,2,3...)
     303                 :      */
     304                 :     int octaveNum;
     305                 :     /**
     306                 :      * Length of the side of filter
     307                 :      */
     308                 :     int filterSize;
     309                 :     /**
     310                 :      * Length of the border
     311                 :      */
     312                 :     int radius;
     313                 :     /**
     314                 :      * Scale for this layer
     315                 :      */
     316                 :     int scale;
     317                 :     /**
     318                 :      * Image width in pixels
     319                 :      */
     320                 :     int width;
     321                 :     /**
     322                 :      * Image height in pixels
     323                 :      */
     324                 :     int height;
     325                 :     /**
     326                 :      * Hessian values for image pixels
     327                 :      */
     328                 :     double **detHessians;
     329                 :     /**
     330                 :      * Hessian signs for speeded matching
     331                 :      */
     332                 :     int **signs;
     333                 : };
     334                 : 
     335                 : /**
     336                 :  * @author Andrew Migal migal.drew@gmail.com
     337                 :  * @brief Class for handling octave layers in SURF-based algorithm.
     338                 :  * @details Class contains OctaveLayers and provides capability to construct octave space and distinguish
     339                 :  * feature points. Normally this class is used only by SURF-based algorithm.
     340                 :  */
     341                 : class GDALOctaveMap
     342                 : {
     343                 : public:
     344                 :     /**
     345                 :      * Create octave space. Octave numbers are start with one. (1, 2, 3, 4, ... )
     346                 :      *
     347                 :      * @param nOctaveStart Number of bottom octave
     348                 :      * @param nOctaveEnd Number of top octave. Should be equal or greater than OctaveStart
     349                 :      */
     350                 :     GDALOctaveMap(int nOctaveStart, int nOctaveEnd);
     351                 :     virtual ~GDALOctaveMap();
     352                 : 
     353                 :     /**
     354                 :      * Calculate Hessian values for octave space
     355                 :      * (for all stored octave layers) using specified integral image
     356                 :      * @param poImg Integral image instance which provides necessary data
     357                 :      * @see GDALOctaveLayer
     358                 :      */
     359                 :     void ComputeMap(GDALIntegralImage *poImg);
     360                 : 
     361                 :     /**
     362                 :      * Method makes decision that specified point
     363                 :      * in middle octave layer is maximum among all points
     364                 :      * from 3x3x3 neighbourhood (surrounding points in
     365                 :      * bottom, middle and top layers). Provided layers should be from the same octave's interval.
     366                 :      * Detects feature points.
     367                 :      *
     368                 :      * @param row Row of point, which is candidate to be feature point
     369                 :      * @param col Column of point, which is candidate to be feature point
     370                 :      * @param bot Bottom octave layer
     371                 :      * @param mid Middle octave layer
     372                 :      * @param top Top octave layer
     373                 :      * @param threshold Threshold for feature point recognition. Detected feature point
     374                 :      * will have Hessian value greater than this provided threshold.
     375                 :      *
     376                 :      * @return TRUE if candidate was evaluated as feature point or FALSE otherwise.
     377                 :      */
     378                 :     bool PointIsExtremum(int row, int col, GDALOctaveLayer *bot,
     379                 :                          GDALOctaveLayer *mid, GDALOctaveLayer *top, double threshold);
     380                 : 
     381                 :     /**
     382                 :      * 2-dimensional array of octave layers
     383                 :      */
     384                 :     GDALOctaveLayer ***pMap;
     385                 : 
     386                 :     /**
     387                 :      * Value for constructing internal octave space
     388                 :      */
     389                 :     static const int INTERVALS = 4;
     390                 : 
     391                 :     /**
     392                 :      * Number of bottom octave
     393                 :      */
     394                 :     int octaveStart;
     395                 : 
     396                 :     /**
     397                 :      * Number of top octave. Should be equal or greater than OctaveStart
     398                 :      */
     399                 :     int octaveEnd;
     400                 : };
     401                 : 
     402                 : /**
     403                 :  * @author Andrew Migal migal.drew@gmail.com
     404                 :  * @brief Class for searching corresponding points on images.
     405                 :  * @details Provides capability for detection feature points
     406                 :  * and finding equal points on different images.
     407                 :  * Class implements simplified version of SURF algorithm (Speeded Up Robust Features).
     408                 :  * As original, this realization is scale invariant, but sensitive to rotation.
     409                 :  * Images should have similar rotation angles (maximum difference is up to 10-15 degrees),
     410                 :  * otherwise algorithm produces incorrect and very unstable results.
     411                 :  */
     412                 : 
     413                 : class GDALSimpleSURF
     414                 : {
     415                 : private:
     416                 :     /**
     417                 :      * Class stores indexes of pair of point
     418                 :      * and distance between them.
     419                 :      */
     420                 :     class MatchedPointPairInfo
     421                 :     {
     422                 :     public:
     423               0 :         MatchedPointPairInfo(int nInd_1, int nInd_2, double dfDist)
     424                 :             {
     425               0 :                 ind_1 = nInd_1;
     426               0 :                 ind_2 = nInd_2;
     427               0 :                 euclideanDist = dfDist;
     428               0 :             }
     429                 : 
     430                 :         int ind_1;
     431                 :         int ind_2;
     432                 :         double euclideanDist;
     433                 :     };
     434                 : 
     435                 : public:
     436                 :     /**
     437                 :      * Prepare class according to specified parameters. Octave numbers affects
     438                 :      * to amount of detected points and their robustness.
     439                 :      * Range between bottom and top octaves also affects to required time of detection points
     440                 :      * (if range is large, algorithm should perform more operations).
     441                 :      * @param nOctaveStart Number of bottom octave. Octave numbers starts with one
     442                 :      * @param nOctaveEnd Number of top octave. Should be equal or greater than OctaveStart
     443                 :      *
     444                 :      * @note
     445                 :      * Every octave finds points with specific size. For small images
     446                 :      * use small octave numbers, for high resolution - large.
     447                 :      * For 1024x1024 images it's normal to use any octave numbers from range 1-6.
     448                 :      * (for example, octave start - 1, octave end - 3, or octave start - 2, octave end - 2.)
     449                 :      * For larger images, try 1-10 range or even higher.
     450                 :      * Pay attention that number of detected point decreases quickly per octave
     451                 :      * for particular image. Algorithm finds more points in case of small octave numbers.
     452                 :      * If method detects nothing, reduce bottom bound of octave range.
     453                 :      *
     454                 :      * NOTICE that every octave requires time to compute. Use a little range
     455                 :      * or only one octave if execution time is significant.
     456                 :      */
     457                 :     GDALSimpleSURF(int nOctaveStart, int nOctaveEnd);
     458                 :     virtual ~GDALSimpleSURF();
     459                 : 
     460                 :     /**
     461                 :      * Convert image with RGB channels to grayscale using "luminosity" method.
     462                 :      * Result is used in SURF-based algorithm, but may be used anywhere where
     463                 :      * grayscale images with nice contrast are required.
     464                 :      *
     465                 :      * @param red Image's red channel
     466                 :      * @param green Image's green channel
     467                 :      * @param blue Image's blue channel
     468                 :      * @param nXSize Width of initial image
     469                 :      * @param nYSize Height of initial image
     470                 :      * @param padfImg Array for resulting grayscale image
     471                 :      * @param nHeight Height of resulting image
     472                 :      * @param nWidth Width of resulting image
     473                 :      *
     474                 :      * @return CE_None or CE_Failure if error occurs.
     475                 :      */
     476                 :     static CPLErr ConvertRGBToLuminosity(
     477                 :         GDALRasterBand *red,
     478                 :         GDALRasterBand *green,
     479                 :         GDALRasterBand *blue,
     480                 :         int nXSize, int nYSize,
     481                 :         double **padfImg, int nHeight, int nWidth);
     482                 : 
     483                 :     /**
     484                 :      * Find feature points using specified integral image.
     485                 :      *
     486                 :      * @param poImg Integral image to be used
     487                 :      * @param dfThreshold Threshold for feature point recognition. Detected feature point
     488                 :      * will have Hessian value greater than this provided threshold.
     489                 :      *
     490                 :      * @note Typical threshold's value is 0,001. But this value
     491                 :      * can be various in each case and depends on image's nature.
     492                 :      * For example, value can be 0.002 or 0.005.
     493                 :      * Fill free to experiment with it.
     494                 :      * If threshold is high, than number of detected feature points is small,
     495                 :      * and vice versa.
     496                 :      */
     497                 :     std::vector<GDALFeaturePoint>*
     498                 :     ExtractFeaturePoints(GDALIntegralImage *poImg, double dfThreshold);
     499                 : 
     500                 :     /**
     501                 :      * Find corresponding points (equal points in two collections).
     502                 :      *
     503                 :      * @param poMatchPairs Resulting collection for matched points
     504                 :      * @param poSecondCollect Points on the first image
     505                 :      * @param poSecondCollect Points on the second image
     506                 :      * @param dfThreshold Value from 0 to 1. Threshold affects to number of
     507                 :      * matched points. If threshold is lower, amount of corresponding
     508                 :      * points is larger, and vice versa
     509                 :      *
     510                 :      * @return CE_None or CE_Failure if error occurs.
     511                 :      */
     512                 :     static CPLErr MatchFeaturePoints(
     513                 :         std::vector<GDALFeaturePoint*> *poMatchPairs,
     514                 :         std::vector<GDALFeaturePoint> *poFirstCollect,
     515                 :         std::vector<GDALFeaturePoint> *poSecondCollect,
     516                 :         double dfThreshold);
     517                 : 
     518                 : private:
     519                 :     /**
     520                 :      * Compute euclidean distance between descriptors of two feature points.
     521                 :      * It's used in comparison and matching of points.
     522                 :      *
     523                 :      * @param firstPoint First feature point to be compared
     524                 :      * @param secondPoint Second feature point to be compared
     525                 :      *
     526                 :      * @return Euclidean distance between descriptors.
     527                 :      */
     528                 :     static double GetEuclideanDistance(
     529                 :         GDALFeaturePoint &firstPoint, GDALFeaturePoint &secondPoint);
     530                 : 
     531                 :     /**
     532                 :      * Set provided distance values to range from 0 to 1.
     533                 :      *
     534                 :      * @param poList List of distances to be normalized
     535                 :      */
     536                 :     static void NormalizeDistances(std::list<MatchedPointPairInfo> *poList);
     537                 : 
     538                 :     /**
     539                 :      * Compute descriptor for specified feature point.
     540                 :      *
     541                 :      * @param poPoint Feature point instance
     542                 :      * @param poImg image where feature point was found
     543                 :      */
     544                 :     void SetDescriptor(GDALFeaturePoint *poPoint, GDALIntegralImage *poImg);
     545                 : 
     546                 : 
     547                 : private:
     548                 :     int octaveStart;
     549                 :     int octaveEnd;
     550                 :     GDALOctaveMap *poOctMap;
     551                 : };
     552                 : 
     553                 : 
     554                 : #endif /* GDALSIMPLESURF_H_ */

Generated by: LCOV version 1.7