gooderp18绿色标准版
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

559 行
17KB

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