sift-conv.tpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // file: sift-conv.tpp
  2. // author: Andrea Vedaldi
  3. // description: Sift template definitions
  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. template<typename T>
  42. void
  43. normalize(T* filter, int W)
  44. {
  45. T acc = 0 ;
  46. T* iter = filter ;
  47. T* end = filter + 2*W+1 ;
  48. while(iter != end) acc += *iter++ ;
  49. iter = filter ;
  50. while(iter != end) *iter++ /= acc ;
  51. }
  52. template<typename T>
  53. void
  54. convolve(T* dst_pt,
  55. const T* src_pt, int M, int N,
  56. const T* filter_pt, int W)
  57. {
  58. typedef T const TC ;
  59. // convolve along columns, save transpose
  60. // image is M by N
  61. // buffer is N by M
  62. // filter is (2*W+1) by 1
  63. for(int j = 0 ; j < N ; ++j) {
  64. int i = 0 ;
  65. // top
  66. for(; i <= std::min(W-1, M-1) ; ++i) {
  67. TC* start = src_pt ;
  68. TC* stop = src_pt + std::min(i+W, M-1) + 1 ;
  69. TC* g = filter_pt + W-i ;
  70. T acc = 0.0 ;
  71. while(stop != start) acc += (*g++) * (*start++) ;
  72. *dst_pt = acc ;
  73. dst_pt += N ;
  74. }
  75. // middle
  76. // run this for W <= i <= M-1-W, only if M >= 2*W+1
  77. for(; i <= M-1-W ; ++i) {
  78. TC* start = src_pt + i-W ;
  79. TC* stop = src_pt + i+W + 1 ;
  80. TC* g = filter_pt ;
  81. T acc = 0.0 ;
  82. while(stop != start) acc += (*g++) * (*start++) ;
  83. *dst_pt = acc ;
  84. dst_pt += N ;
  85. }
  86. // bottom
  87. // run this for M-W <= i <= M-1, only if M >= 2*W+1
  88. for(; i <= M-1 ; ++i) {
  89. TC* start = src_pt + i-W ;
  90. TC* stop = src_pt + std::min(i+W, M-1) + 1 ;
  91. TC* g = filter_pt ;
  92. T acc = 0.0 ;
  93. while(stop != start) acc += (*g++) * (*start++) ;
  94. *dst_pt = acc ;
  95. dst_pt += N ;
  96. }
  97. // next column
  98. src_pt += M ;
  99. dst_pt -= M*N - 1 ;
  100. }
  101. }
  102. // works with symmetric filters only
  103. template<typename T>
  104. void
  105. nconvolve(T* dst_pt,
  106. const T* src_pt, int M, int N,
  107. const T* filter_pt, int W,
  108. T* scratch_pt )
  109. {
  110. typedef T const TC ;
  111. for(int i = 0 ; i <= W ; ++i) {
  112. T acc = 0.0 ;
  113. TC* iter = filter_pt + std::max(W-i, 0) ;
  114. TC* stop = filter_pt + std::min(M-1-i,W) + W + 1 ;
  115. while(iter != stop) acc += *iter++ ;
  116. scratch_pt [i] = acc ;
  117. }
  118. for(int j = 0 ; j < N ; ++j) {
  119. int i = 0 ;
  120. // top margin
  121. for(; i <= std::min(W, M-1) ; ++i) {
  122. TC* start = src_pt ;
  123. TC* stop = src_pt + std::min(i+W, M-1) + 1 ;
  124. TC* g = filter_pt + W-i ;
  125. T acc = 0.0 ;
  126. while(stop != start) acc += (*g++) * (*start++) ;
  127. *dst_pt = acc / scratch_pt [i] ;
  128. dst_pt += N ;
  129. }
  130. // middle
  131. for(; i <= M-1-W ; ++i) {
  132. TC* start = src_pt + i-W ;
  133. TC* stop = src_pt + i+W + 1 ;
  134. TC* g = filter_pt ;
  135. T acc = 0.0 ;
  136. while(stop != start) acc += (*g++) * (*start++) ;
  137. *dst_pt = acc ;
  138. dst_pt += N ;
  139. }
  140. // bottom
  141. for(; i <= M-1 ; ++i) {
  142. TC* start = src_pt + i-W ;
  143. TC* stop = src_pt + std::min(i+W, M-1) + 1 ;
  144. TC* g = filter_pt ;
  145. T acc = 0.0 ;
  146. while(stop != start) acc += (*g++) * (*start++) ;
  147. *dst_pt = acc / scratch_pt [M-1-i];
  148. dst_pt += N ;
  149. }
  150. // next column
  151. src_pt += M ;
  152. dst_pt -= M*N - 1 ;
  153. }
  154. }
  155. template<typename T>
  156. void
  157. econvolve(T* dst_pt,
  158. const T* src_pt, int M, int N,
  159. const T* filter_pt, int W)
  160. {
  161. typedef T const TC ;
  162. // convolve along columns, save transpose
  163. // image is M by N
  164. // buffer is N by M
  165. // filter is (2*W+1) by 1
  166. for(int j = 0 ; j < N ; ++j) {
  167. for(int i = 0 ; i < M ; ++i) {
  168. T acc = 0.0 ;
  169. TC* g = filter_pt ;
  170. TC* start = src_pt + (i-W) ;
  171. TC* stop ;
  172. T x ;
  173. // beginning
  174. stop = src_pt + std::max(0, i-W) ;
  175. x = *stop ;
  176. while( start <= stop ) { acc += (*g++) * x ; start++ ; }
  177. // middle
  178. stop = src_pt + std::min(M-1, i+W) ;
  179. while( start < stop ) acc += (*g++) * (*start++) ;
  180. // end
  181. x = *start ;
  182. stop = src_pt + (i+W) ;
  183. while( start <= stop ) { acc += (*g++) * x ; start++ ; }
  184. // save
  185. *dst_pt = acc ;
  186. dst_pt += N ;
  187. assert( g - filter_pt == 2*W+1 ) ;
  188. }
  189. // next column
  190. src_pt += M ;
  191. dst_pt -= M*N - 1 ;
  192. }
  193. }
  194. // Emacs:
  195. // Local Variables:
  196. // mode: C++
  197. // End: