sift.ipp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. // file: sift.ipp
  2. // author: Andrea Vedaldi
  3. // description: Sift inline members definition
  4. // AUTORIGHTS
  5. // Copyright (c) 2006 The Regents of the University of California
  6. // All Rights Reserved.
  7. //
  8. // Created by Andrea Vedaldi (UCLA VisionLab)
  9. //
  10. // Permission to use, copy, modify, and distribute this software and its
  11. // documentation for educational, research and non-profit purposes,
  12. // without fee, and without a written agreement is hereby granted,
  13. // provided that the above copyright notice, this paragraph and the
  14. // following three paragraphs appear in all copies.
  15. //
  16. // This software program and documentation are copyrighted by The Regents
  17. // of the University of California. The software program and
  18. // documentation are supplied "as is", without any accompanying services
  19. // from The Regents. The Regents does not warrant that the operation of
  20. // the program will be uninterrupted or error-free. The end-user
  21. // understands that the program was developed for research purposes and
  22. // is advised not to rely exclusively on the program for any reason.
  23. //
  24. // This software embodies a method for which the following patent has
  25. // been issued: "Method and apparatus for identifying scale invariant
  26. // features in an image and use of same for locating an object in an
  27. // image," David G. Lowe, US Patent 6,711,293 (March 23,
  28. // 2004). Provisional application filed March 8, 1999. Asignee: The
  29. // University of British Columbia.
  30. //
  31. // IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
  32. // FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
  33. // INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND
  34. // ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN
  35. // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF
  36. // CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
  37. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  38. // A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
  39. // BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE
  40. // MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  41. /**
  42. ** @file
  43. ** @brief SIFT class - inline functions and members
  44. **/
  45. #include<iostream>
  46. #include<cassert>
  47. namespace VL
  48. {
  49. namespace Detail
  50. {
  51. extern int const expnTableSize ;
  52. extern VL::float_t const expnTableMax ;
  53. extern VL::float_t expnTable [] ;
  54. }
  55. /** @brief Get width of source image
  56. ** @result width.
  57. **/
  58. inline
  59. int
  60. Sift::getWidth() const
  61. {
  62. return width ;
  63. }
  64. /** @brief Get height of source image
  65. ** @result height.
  66. **/
  67. inline
  68. int
  69. Sift::getHeight() const
  70. {
  71. return height ;
  72. }
  73. /** @brief Get width of an octave
  74. ** @param o octave index.
  75. ** @result width of octave @a o.
  76. **/
  77. inline
  78. int
  79. Sift::getOctaveWidth(int o) const
  80. {
  81. assert( omin <= o && o < omin + O ) ;
  82. return (o >= 0) ? (width >> o) : (width << -o) ;
  83. }
  84. /** @brief Get height of an octave
  85. ** @param o octave index.
  86. ** @result height of octave @a o.
  87. **/
  88. inline
  89. int
  90. Sift::getOctaveHeight(int o) const
  91. {
  92. assert( omin <= o && o < omin + O ) ;
  93. return (o >= 0) ? (height >> o) : (height << -o) ;
  94. }
  95. /** @brief Get octave
  96. ** @param o octave index.
  97. ** @return pointer to octave @a o.
  98. **/
  99. inline
  100. VL::pixel_t *
  101. Sift::getOctave(int o)
  102. {
  103. assert( omin <= o && o < omin + O ) ;
  104. return octaves[o-omin] ;
  105. }
  106. /** @brief Get level
  107. ** @param o octave index.
  108. ** @param s level index.
  109. ** @result pointer to level @c (o,s).
  110. **/
  111. inline
  112. VL::pixel_t *
  113. Sift::getLevel(int o, int s)
  114. {
  115. assert( omin <= o && o < omin + O ) ;
  116. assert( smin <= s && s <= smax ) ;
  117. return octaves[o - omin] +
  118. getOctaveWidth(o)*getOctaveHeight(o) * (s-smin) ;
  119. }
  120. /** @brief Get octave sampling period
  121. ** @param o octave index.
  122. ** @result Octave sampling period (in pixels).
  123. **/
  124. inline
  125. VL::float_t
  126. Sift::getOctaveSamplingPeriod(int o) const
  127. {
  128. return (o >= 0) ? (1 << o) : 1.0f / (1 << -o) ;
  129. }
  130. /** @brief Convert index into scale
  131. ** @param o octave index.
  132. ** @param s scale index.
  133. ** @return scale.
  134. **/
  135. inline
  136. VL::float_t
  137. Sift::getScaleFromIndex(VL::float_t o, VL::float_t s) const
  138. {
  139. return sigma0 * powf( 2.0f, o + s / S ) ;
  140. }
  141. /** @brief Get keypoint list begin
  142. ** @return iterator to the beginning.
  143. **/
  144. inline
  145. Sift::KeypointsIter
  146. Sift::keypointsBegin()
  147. {
  148. return keypoints.begin() ;
  149. }
  150. /** @brief Get keypoint list end
  151. ** @return iterator to the end.
  152. **/
  153. inline
  154. Sift::KeypointsIter
  155. Sift::keypointsEnd()
  156. {
  157. return keypoints.end() ;
  158. }
  159. /** @brief Set normalize descriptor flag */
  160. inline
  161. void
  162. Sift::setNormalizeDescriptor(bool flag)
  163. {
  164. normalizeDescriptor = flag ;
  165. }
  166. /** @brief Get normalize descriptor flag */
  167. inline
  168. bool
  169. Sift::getNormalizeDescriptor() const
  170. {
  171. return normalizeDescriptor ;
  172. }
  173. /** @brief Set descriptor magnification */
  174. inline
  175. void
  176. Sift::setMagnification(VL::float_t _magnif)
  177. {
  178. magnif = _magnif ;
  179. }
  180. /** @brief Get descriptor magnification */
  181. inline
  182. VL::float_t
  183. Sift::getMagnification() const
  184. {
  185. return magnif ;
  186. }
  187. /** @brief Fast @ exp(-x)
  188. **
  189. ** The argument must be in the range 0-25.0 (bigger arguments may be
  190. ** truncated to zero).
  191. **
  192. ** @param x argument.
  193. ** @return @c exp(-x)
  194. **/
  195. inline
  196. VL::float_t
  197. fast_expn(VL::float_t x)
  198. {
  199. assert(VL::float_t(0) <= x && x <= Detail::expnTableMax) ;
  200. #ifdef VL_USEFASTMATH
  201. x *= Detail::expnTableSize / Detail::expnTableMax ;
  202. VL::int32_t i = fast_floor(x) ;
  203. VL::float_t r = x - i ;
  204. VL::float_t a = VL::Detail::expnTable[i] ;
  205. VL::float_t b = VL::Detail::expnTable[i+1] ;
  206. return a + r * (b - a) ;
  207. #else
  208. return exp(-x) ;
  209. #endif
  210. }
  211. /** @brief Fast @c mod(x,2pi)
  212. **
  213. ** The function quickly computes the value @c mod(x,2pi).
  214. **
  215. ** @remark The computation is fast only for arguments @a x which are
  216. ** small in modulus.
  217. **
  218. ** @remark For negative arguments, the semantic of the function is
  219. ** not equivalent to the standard library @c fmod function.
  220. **
  221. ** @param x function argument.
  222. ** @return @c mod(x,2pi)
  223. **/
  224. inline
  225. VL::float_t
  226. fast_mod_2pi(VL::float_t x)
  227. {
  228. #ifdef VL_USEFASTMATH
  229. while(x < VL::float_t(0) ) x += VL::float_t(2*M_PI) ;
  230. while(x > VL::float_t(2*M_PI) ) x -= VL::float_t(2*M_PI) ;
  231. return x ;
  232. #else
  233. return (x>=0) ? std::fmod(x, VL::float_t(2*M_PI))
  234. : 2*M_PI + std::fmod(x, VL::float_t(2*M_PI)) ;
  235. #endif
  236. }
  237. /** @brief Fast @c (int) floor(x)
  238. ** @param x argument.
  239. ** @return @c float(x)
  240. **/
  241. inline
  242. int32_t
  243. fast_floor(VL::float_t x)
  244. {
  245. #ifdef VL_USEFASTMATH
  246. return (x>=0)? int32_t(x) : std::floor(x) ;
  247. // return int32_t( x - ((x>=0)?0:1) ) ;
  248. #else
  249. return int32_t( std::floor(x) ) ;
  250. #endif
  251. }
  252. /** @brief Fast @c abs(x)
  253. ** @param x argument.
  254. ** @return @c abs(x)
  255. **/
  256. inline
  257. VL::float_t
  258. fast_abs(VL::float_t x)
  259. {
  260. #ifdef VL_USEFASTMATH
  261. return (x >= 0) ? x : -x ;
  262. #else
  263. return std::fabs(x) ;
  264. #endif
  265. }
  266. /** @brief Fast @c atan2
  267. ** @param x argument.
  268. ** @param y argument.
  269. ** @return Approximation of @c atan2(x).
  270. **/
  271. inline
  272. VL::float_t
  273. fast_atan2(VL::float_t y, VL::float_t x)
  274. {
  275. #ifdef VL_USEFASTMATH
  276. /*
  277. The function f(r)=atan((1-r)/(1+r)) for r in [-1,1] is easier to
  278. approximate than atan(z) for z in [0,inf]. To approximate f(r) to
  279. the third degree we may solve the system
  280. f(+1) = c0 + c1 + c2 + c3 = atan(0) = 0
  281. f(-1) = c0 - c1 + c2 - c3 = atan(inf) = pi/2
  282. f(0) = c0 = atan(1) = pi/4
  283. which constrains the polynomial to go through the end points and
  284. the middle point.
  285. We still miss a constrain, which might be simply a constarint on
  286. the derivative in 0. Instead we minimize the Linf error in the
  287. range [0,1] by searching for an optimal value of the free
  288. parameter. This turns out to correspond to the solution
  289. c0=pi/4, c1=-0.9675, c2=0, c3=0.1821
  290. which has maxerr = 0.0061 rad = 0.35 grad.
  291. */
  292. VL::float_t angle, r ;
  293. VL::float_t const c3 = 0.1821 ;
  294. VL::float_t const c1 = 0.9675 ;
  295. VL::float_t abs_y = fast_abs(y) + VL::float_t(1e-10) ;
  296. if (x >= 0) {
  297. r = (x - abs_y) / (x + abs_y) ;
  298. angle = VL::float_t(M_PI/4.0) ;
  299. } else {
  300. r = (x + abs_y) / (abs_y - x) ;
  301. angle = VL::float_t(3*M_PI/4.0) ;
  302. }
  303. angle += (c3*r*r - c1) * r ;
  304. return (y < 0) ? -angle : angle ;
  305. #else
  306. return std::atan2(y,x) ;
  307. #endif
  308. }
  309. /** @brief Fast @c resqrt
  310. ** @param x argument.
  311. ** @return Approximation to @c resqrt(x).
  312. **/
  313. inline
  314. float
  315. fast_resqrt(float x)
  316. {
  317. #ifdef VL_USEFASTMATH
  318. // Works if VL::float_t is 32 bit ...
  319. union {
  320. float x ;
  321. VL::int32_t i ;
  322. } u ;
  323. float xhalf = float(0.5) * x ;
  324. u.x = x ; // get bits for floating value
  325. u.i = 0x5f3759df - (u.i>>1); // gives initial guess y0
  326. //u.i = 0xdf59375f - (u.i>>1); // gives initial guess y0
  327. u.x = u.x*(float(1.5) - xhalf*u.x*u.x); // Newton step (may repeat)
  328. u.x = u.x*(float(1.5) - xhalf*u.x*u.x); // Newton step (may repeat)
  329. return u.x ;
  330. #else
  331. return float(1.0) / std::sqrt(x) ;
  332. #endif
  333. }
  334. /** @brief Fast @c resqrt
  335. ** @param x argument.
  336. ** @return Approximation to @c resqrt(x).
  337. **/
  338. inline
  339. double
  340. fast_resqrt(double x)
  341. {
  342. #ifdef VL_USEFASTMATH
  343. // Works if double is 64 bit ...
  344. union {
  345. double x ;
  346. VL::int64_t i ;
  347. } u ;
  348. double xhalf = double(0.5) * x ;
  349. u.x = x ; // get bits for floating value
  350. u.i = 0x5fe6ec85e7de30daLL - (u.i>>1); // gives initial guess y0
  351. u.x = u.x*(double(1.5) - xhalf*u.x*u.x); // Newton step (may repeat)
  352. u.x = u.x*(double(1.5) - xhalf*u.x*u.x); // Newton step (may repeat)
  353. return u.x ;
  354. #else
  355. return double(1.0) / std::sqrt(x) ;
  356. #endif
  357. }
  358. /** @brief Fast @c sqrt
  359. ** @param x argument.
  360. ** @return Approximation to @c sqrt(x).
  361. **/
  362. inline
  363. VL::float_t
  364. fast_sqrt(VL::float_t x)
  365. {
  366. #ifdef VL_USEFASTMATH
  367. return (x < 1e-8) ? 0 : x * fast_resqrt(x) ;
  368. #else
  369. return std::sqrt(x) ;
  370. #endif
  371. }
  372. }
  373. // Emacs:
  374. // Local Variables:
  375. // mode: C++
  376. // End: