dist.h 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293
  1. /***********************************************************************
  2. * Software License Agreement (BSD License)
  3. *
  4. * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
  5. * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
  6. *
  7. * THE BSD LICENSE
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. *
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  20. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  21. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  23. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  24. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  28. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *************************************************************************/
  30. #ifndef OPENCV_FLANN_DIST_H_
  31. #define OPENCV_FLANN_DIST_H_
  32. //! @cond IGNORED
  33. #include <cmath>
  34. #include <cstdlib>
  35. #include <string.h>
  36. #ifdef _MSC_VER
  37. typedef unsigned __int32 uint32_t;
  38. typedef unsigned __int64 uint64_t;
  39. #else
  40. #include <stdint.h>
  41. #endif
  42. #include "defines.h"
  43. #if defined _WIN32 && (defined(_M_ARM) || defined(_M_ARM64))
  44. # include <Intrin.h>
  45. #endif
  46. #if defined(__ARM_NEON__) && !defined(__CUDACC__)
  47. # include "arm_neon.h"
  48. #endif
  49. namespace cvflann
  50. {
  51. template<typename T>
  52. inline T abs(T x) { return (x<0) ? -x : x; }
  53. template<>
  54. inline int abs<int>(int x) { return ::abs(x); }
  55. template<>
  56. inline float abs<float>(float x) { return fabsf(x); }
  57. template<>
  58. inline double abs<double>(double x) { return fabs(x); }
  59. template<typename TargetType>
  60. inline TargetType round(float x) { return static_cast<TargetType>(x); }
  61. template<>
  62. inline unsigned int round<unsigned int>(float x) { return static_cast<unsigned int>(x + 0.5f); }
  63. template<>
  64. inline unsigned short round<unsigned short>(float x) { return static_cast<unsigned short>(x + 0.5f); }
  65. template<>
  66. inline unsigned char round<unsigned char>(float x) { return static_cast<unsigned char>(x + 0.5f); }
  67. template<>
  68. inline long long round<long long>(float x) { return static_cast<long long>(x + 0.5f); }
  69. template<>
  70. inline long round<long>(float x) { return static_cast<long>(x + 0.5f); }
  71. template<>
  72. inline int round<int>(float x) { return static_cast<int>(x + 0.5f) - (x<0); }
  73. template<>
  74. inline short round<short>(float x) { return static_cast<short>(x + 0.5f) - (x<0); }
  75. template<>
  76. inline char round<char>(float x) { return static_cast<char>(x + 0.5f) - (x<0); }
  77. template<typename TargetType>
  78. inline TargetType round(double x) { return static_cast<TargetType>(x); }
  79. template<>
  80. inline unsigned int round<unsigned int>(double x) { return static_cast<unsigned int>(x + 0.5); }
  81. template<>
  82. inline unsigned short round<unsigned short>(double x) { return static_cast<unsigned short>(x + 0.5); }
  83. template<>
  84. inline unsigned char round<unsigned char>(double x) { return static_cast<unsigned char>(x + 0.5); }
  85. template<>
  86. inline long long round<long long>(double x) { return static_cast<long long>(x + 0.5); }
  87. template<>
  88. inline long round<long>(double x) { return static_cast<long>(x + 0.5); }
  89. template<>
  90. inline int round<int>(double x) { return static_cast<int>(x + 0.5) - (x<0); }
  91. template<>
  92. inline short round<short>(double x) { return static_cast<short>(x + 0.5) - (x<0); }
  93. template<>
  94. inline char round<char>(double x) { return static_cast<char>(x + 0.5) - (x<0); }
  95. template<typename T>
  96. struct Accumulator { typedef T Type; };
  97. template<>
  98. struct Accumulator<unsigned char> { typedef float Type; };
  99. template<>
  100. struct Accumulator<unsigned short> { typedef float Type; };
  101. template<>
  102. struct Accumulator<unsigned int> { typedef float Type; };
  103. template<>
  104. struct Accumulator<char> { typedef float Type; };
  105. template<>
  106. struct Accumulator<short> { typedef float Type; };
  107. template<>
  108. struct Accumulator<int> { typedef float Type; };
  109. #undef True
  110. #undef False
  111. class True
  112. {
  113. public:
  114. static const bool val = true;
  115. };
  116. class False
  117. {
  118. public:
  119. static const bool val = false;
  120. };
  121. /*
  122. * This is a "zero iterator". It basically behaves like a zero filled
  123. * array to all algorithms that use arrays as iterators (STL style).
  124. * It's useful when there's a need to compute the distance between feature
  125. * and origin it and allows for better compiler optimisation than using a
  126. * zero-filled array.
  127. */
  128. template <typename T>
  129. struct ZeroIterator
  130. {
  131. T operator*()
  132. {
  133. return 0;
  134. }
  135. T operator[](int)
  136. {
  137. return 0;
  138. }
  139. const ZeroIterator<T>& operator ++()
  140. {
  141. return *this;
  142. }
  143. ZeroIterator<T> operator ++(int)
  144. {
  145. return *this;
  146. }
  147. ZeroIterator<T>& operator+=(int)
  148. {
  149. return *this;
  150. }
  151. };
  152. /**
  153. * Squared Euclidean distance functor.
  154. *
  155. * This is the simpler, unrolled version. This is preferable for
  156. * very low dimensionality data (eg 3D points)
  157. */
  158. template<class T>
  159. struct L2_Simple
  160. {
  161. typedef True is_kdtree_distance;
  162. typedef True is_vector_space_distance;
  163. typedef T ElementType;
  164. typedef typename Accumulator<T>::Type ResultType;
  165. typedef ResultType CentersType;
  166. template <typename Iterator1, typename Iterator2>
  167. ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
  168. {
  169. ResultType result = ResultType();
  170. ResultType diff;
  171. for(size_t i = 0; i < size; ++i ) {
  172. diff = (ResultType)(*a++ - *b++);
  173. result += diff*diff;
  174. }
  175. return result;
  176. }
  177. template <typename U, typename V>
  178. inline ResultType accum_dist(const U& a, const V& b, int) const
  179. {
  180. return (a-b)*(a-b);
  181. }
  182. };
  183. /**
  184. * Squared Euclidean distance functor, optimized version
  185. */
  186. template<class T>
  187. struct L2
  188. {
  189. typedef True is_kdtree_distance;
  190. typedef True is_vector_space_distance;
  191. typedef T ElementType;
  192. typedef typename Accumulator<T>::Type ResultType;
  193. typedef ResultType CentersType;
  194. /**
  195. * Compute the squared Euclidean distance between two vectors.
  196. *
  197. * This is highly optimised, with loop unrolling, as it is one
  198. * of the most expensive inner loops.
  199. *
  200. * The computation of squared root at the end is omitted for
  201. * efficiency.
  202. */
  203. template <typename Iterator1, typename Iterator2>
  204. ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
  205. {
  206. ResultType result = ResultType();
  207. ResultType diff0, diff1, diff2, diff3;
  208. Iterator1 last = a + size;
  209. Iterator1 lastgroup = last - 3;
  210. /* Process 4 items with each loop for efficiency. */
  211. while (a < lastgroup) {
  212. diff0 = (ResultType)(a[0] - b[0]);
  213. diff1 = (ResultType)(a[1] - b[1]);
  214. diff2 = (ResultType)(a[2] - b[2]);
  215. diff3 = (ResultType)(a[3] - b[3]);
  216. result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
  217. a += 4;
  218. b += 4;
  219. if ((worst_dist>0)&&(result>worst_dist)) {
  220. return result;
  221. }
  222. }
  223. /* Process last 0-3 pixels. Not needed for standard vector lengths. */
  224. while (a < last) {
  225. diff0 = (ResultType)(*a++ - *b++);
  226. result += diff0 * diff0;
  227. }
  228. return result;
  229. }
  230. /**
  231. * Partial euclidean distance, using just one dimension. This is used by the
  232. * kd-tree when computing partial distances while traversing the tree.
  233. *
  234. * Squared root is omitted for efficiency.
  235. */
  236. template <typename U, typename V>
  237. inline ResultType accum_dist(const U& a, const V& b, int) const
  238. {
  239. return (a-b)*(a-b);
  240. }
  241. };
  242. /*
  243. * Manhattan distance functor, optimized version
  244. */
  245. template<class T>
  246. struct L1
  247. {
  248. typedef True is_kdtree_distance;
  249. typedef True is_vector_space_distance;
  250. typedef T ElementType;
  251. typedef typename Accumulator<T>::Type ResultType;
  252. typedef ResultType CentersType;
  253. /**
  254. * Compute the Manhattan (L_1) distance between two vectors.
  255. *
  256. * This is highly optimised, with loop unrolling, as it is one
  257. * of the most expensive inner loops.
  258. */
  259. template <typename Iterator1, typename Iterator2>
  260. ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
  261. {
  262. ResultType result = ResultType();
  263. ResultType diff0, diff1, diff2, diff3;
  264. Iterator1 last = a + size;
  265. Iterator1 lastgroup = last - 3;
  266. /* Process 4 items with each loop for efficiency. */
  267. while (a < lastgroup) {
  268. diff0 = (ResultType)abs(a[0] - b[0]);
  269. diff1 = (ResultType)abs(a[1] - b[1]);
  270. diff2 = (ResultType)abs(a[2] - b[2]);
  271. diff3 = (ResultType)abs(a[3] - b[3]);
  272. result += diff0 + diff1 + diff2 + diff3;
  273. a += 4;
  274. b += 4;
  275. if ((worst_dist>0)&&(result>worst_dist)) {
  276. return result;
  277. }
  278. }
  279. /* Process last 0-3 pixels. Not needed for standard vector lengths. */
  280. while (a < last) {
  281. diff0 = (ResultType)abs(*a++ - *b++);
  282. result += diff0;
  283. }
  284. return result;
  285. }
  286. /**
  287. * Partial distance, used by the kd-tree.
  288. */
  289. template <typename U, typename V>
  290. inline ResultType accum_dist(const U& a, const V& b, int) const
  291. {
  292. return abs(a-b);
  293. }
  294. };
  295. template<class T>
  296. struct MinkowskiDistance
  297. {
  298. typedef True is_kdtree_distance;
  299. typedef True is_vector_space_distance;
  300. typedef T ElementType;
  301. typedef typename Accumulator<T>::Type ResultType;
  302. typedef ResultType CentersType;
  303. int order;
  304. MinkowskiDistance(int order_) : order(order_) {}
  305. /**
  306. * Compute the Minkowsky (L_p) distance between two vectors.
  307. *
  308. * This is highly optimised, with loop unrolling, as it is one
  309. * of the most expensive inner loops.
  310. *
  311. * The computation of squared root at the end is omitted for
  312. * efficiency.
  313. */
  314. template <typename Iterator1, typename Iterator2>
  315. ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
  316. {
  317. ResultType result = ResultType();
  318. ResultType diff0, diff1, diff2, diff3;
  319. Iterator1 last = a + size;
  320. Iterator1 lastgroup = last - 3;
  321. /* Process 4 items with each loop for efficiency. */
  322. while (a < lastgroup) {
  323. diff0 = (ResultType)abs(a[0] - b[0]);
  324. diff1 = (ResultType)abs(a[1] - b[1]);
  325. diff2 = (ResultType)abs(a[2] - b[2]);
  326. diff3 = (ResultType)abs(a[3] - b[3]);
  327. result += pow(diff0,order) + pow(diff1,order) + pow(diff2,order) + pow(diff3,order);
  328. a += 4;
  329. b += 4;
  330. if ((worst_dist>0)&&(result>worst_dist)) {
  331. return result;
  332. }
  333. }
  334. /* Process last 0-3 pixels. Not needed for standard vector lengths. */
  335. while (a < last) {
  336. diff0 = (ResultType)abs(*a++ - *b++);
  337. result += pow(diff0,order);
  338. }
  339. return result;
  340. }
  341. /**
  342. * Partial distance, used by the kd-tree.
  343. */
  344. template <typename U, typename V>
  345. inline ResultType accum_dist(const U& a, const V& b, int) const
  346. {
  347. return pow(static_cast<ResultType>(abs(a-b)),order);
  348. }
  349. };
  350. template<class T>
  351. struct MaxDistance
  352. {
  353. typedef False is_kdtree_distance;
  354. typedef True is_vector_space_distance;
  355. typedef T ElementType;
  356. typedef typename Accumulator<T>::Type ResultType;
  357. typedef ResultType CentersType;
  358. /**
  359. * Compute the max distance (L_infinity) between two vectors.
  360. *
  361. * This distance is not a valid kdtree distance, it's not dimensionwise additive.
  362. */
  363. template <typename Iterator1, typename Iterator2>
  364. ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
  365. {
  366. ResultType result = ResultType();
  367. ResultType diff0, diff1, diff2, diff3;
  368. Iterator1 last = a + size;
  369. Iterator1 lastgroup = last - 3;
  370. /* Process 4 items with each loop for efficiency. */
  371. while (a < lastgroup) {
  372. diff0 = abs(a[0] - b[0]);
  373. diff1 = abs(a[1] - b[1]);
  374. diff2 = abs(a[2] - b[2]);
  375. diff3 = abs(a[3] - b[3]);
  376. if (diff0>result) {result = diff0; }
  377. if (diff1>result) {result = diff1; }
  378. if (diff2>result) {result = diff2; }
  379. if (diff3>result) {result = diff3; }
  380. a += 4;
  381. b += 4;
  382. if ((worst_dist>0)&&(result>worst_dist)) {
  383. return result;
  384. }
  385. }
  386. /* Process last 0-3 pixels. Not needed for standard vector lengths. */
  387. while (a < last) {
  388. diff0 = abs(*a++ - *b++);
  389. result = (diff0>result) ? diff0 : result;
  390. }
  391. return result;
  392. }
  393. /* This distance functor is not dimension-wise additive, which
  394. * makes it an invalid kd-tree distance, not implementing the accum_dist method */
  395. };
  396. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  397. /**
  398. * Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor
  399. * bit count of A exclusive XOR'ed with B
  400. */
  401. struct HammingLUT
  402. {
  403. typedef False is_kdtree_distance;
  404. typedef False is_vector_space_distance;
  405. typedef unsigned char ElementType;
  406. typedef int ResultType;
  407. typedef ElementType CentersType;
  408. /** this will count the bits in a ^ b
  409. */
  410. template<typename Iterator2>
  411. ResultType operator()(const unsigned char* a, const Iterator2 b, size_t size) const
  412. {
  413. static const uchar popCountTable[] =
  414. {
  415. 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  416. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  417. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  418. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  419. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  420. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  421. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  422. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
  423. };
  424. ResultType result = 0;
  425. const unsigned char* b2 = reinterpret_cast<const unsigned char*> (b);
  426. for (size_t i = 0; i < size; i++) {
  427. result += popCountTable[a[i] ^ b2[i]];
  428. }
  429. return result;
  430. }
  431. ResultType operator()(const unsigned char* a, const ZeroIterator<unsigned char> b, size_t size) const
  432. {
  433. (void)b;
  434. static const uchar popCountTable[] =
  435. {
  436. 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  437. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  438. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  439. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  440. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  441. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  442. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  443. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
  444. };
  445. ResultType result = 0;
  446. for (size_t i = 0; i < size; i++) {
  447. result += popCountTable[a[i]];
  448. }
  449. return result;
  450. }
  451. };
  452. /**
  453. * Hamming distance functor (pop count between two binary vectors, i.e. xor them and count the number of bits set)
  454. * That code was taken from brief.cpp in OpenCV
  455. */
  456. template<class T>
  457. struct Hamming
  458. {
  459. typedef False is_kdtree_distance;
  460. typedef False is_vector_space_distance;
  461. typedef T ElementType;
  462. typedef int ResultType;
  463. typedef ElementType CentersType;
  464. template<typename Iterator1, typename Iterator2>
  465. ResultType operator()(const Iterator1 a, const Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
  466. {
  467. ResultType result = 0;
  468. #if defined(__ARM_NEON__) && !defined(__CUDACC__)
  469. {
  470. const unsigned char* a2 = reinterpret_cast<const unsigned char*> (a);
  471. const unsigned char* b2 = reinterpret_cast<const unsigned char*> (b);
  472. uint32x4_t bits = vmovq_n_u32(0);
  473. for (size_t i = 0; i < size; i += 16) {
  474. uint8x16_t A_vec = vld1q_u8 (a2 + i);
  475. uint8x16_t B_vec = vld1q_u8 (b2 + i);
  476. uint8x16_t AxorB = veorq_u8 (A_vec, B_vec);
  477. uint8x16_t bitsSet = vcntq_u8 (AxorB);
  478. uint16x8_t bitSet8 = vpaddlq_u8 (bitsSet);
  479. uint32x4_t bitSet4 = vpaddlq_u16 (bitSet8);
  480. bits = vaddq_u32(bits, bitSet4);
  481. }
  482. uint64x2_t bitSet2 = vpaddlq_u32 (bits);
  483. result = vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),0);
  484. result += vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),2);
  485. }
  486. #elif defined(__GNUC__)
  487. {
  488. //for portability just use unsigned long -- and use the __builtin_popcountll (see docs for __builtin_popcountll)
  489. typedef unsigned long long pop_t;
  490. const size_t modulo = size % sizeof(pop_t);
  491. const pop_t* a2 = reinterpret_cast<const pop_t*> (a);
  492. const pop_t* b2 = reinterpret_cast<const pop_t*> (b);
  493. const pop_t* a2_end = a2 + (size / sizeof(pop_t));
  494. for (; a2 != a2_end; ++a2, ++b2) result += __builtin_popcountll((*a2) ^ (*b2));
  495. if (modulo) {
  496. //in the case where size is not dividable by sizeof(size_t)
  497. //need to mask off the bits at the end
  498. pop_t a_final = 0, b_final = 0;
  499. memcpy(&a_final, a2, modulo);
  500. memcpy(&b_final, b2, modulo);
  501. result += __builtin_popcountll(a_final ^ b_final);
  502. }
  503. }
  504. #else // NO NEON and NOT GNUC
  505. HammingLUT lut;
  506. result = lut(reinterpret_cast<const unsigned char*> (a),
  507. reinterpret_cast<const unsigned char*> (b), size);
  508. #endif
  509. return result;
  510. }
  511. template<typename Iterator1>
  512. ResultType operator()(const Iterator1 a, ZeroIterator<unsigned char> b, size_t size, ResultType /*worst_dist*/ = -1) const
  513. {
  514. (void)b;
  515. ResultType result = 0;
  516. #if defined(__ARM_NEON__) && !defined(__CUDACC__)
  517. {
  518. const unsigned char* a2 = reinterpret_cast<const unsigned char*> (a);
  519. uint32x4_t bits = vmovq_n_u32(0);
  520. for (size_t i = 0; i < size; i += 16) {
  521. uint8x16_t A_vec = vld1q_u8 (a2 + i);
  522. uint8x16_t bitsSet = vcntq_u8 (A_vec);
  523. uint16x8_t bitSet8 = vpaddlq_u8 (bitsSet);
  524. uint32x4_t bitSet4 = vpaddlq_u16 (bitSet8);
  525. bits = vaddq_u32(bits, bitSet4);
  526. }
  527. uint64x2_t bitSet2 = vpaddlq_u32 (bits);
  528. result = vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),0);
  529. result += vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),2);
  530. }
  531. #elif defined(__GNUC__)
  532. {
  533. //for portability just use unsigned long -- and use the __builtin_popcountll (see docs for __builtin_popcountll)
  534. typedef unsigned long long pop_t;
  535. const size_t modulo = size % sizeof(pop_t);
  536. const pop_t* a2 = reinterpret_cast<const pop_t*> (a);
  537. const pop_t* a2_end = a2 + (size / sizeof(pop_t));
  538. for (; a2 != a2_end; ++a2) result += __builtin_popcountll(*a2);
  539. if (modulo) {
  540. //in the case where size is not dividable by sizeof(size_t)
  541. //need to mask off the bits at the end
  542. pop_t a_final = 0;
  543. memcpy(&a_final, a2, modulo);
  544. result += __builtin_popcountll(a_final);
  545. }
  546. }
  547. #else // NO NEON and NOT GNUC
  548. HammingLUT lut;
  549. result = lut(reinterpret_cast<const unsigned char*> (a), b, size);
  550. #endif
  551. return result;
  552. }
  553. };
  554. template<typename T>
  555. struct Hamming2
  556. {
  557. typedef False is_kdtree_distance;
  558. typedef False is_vector_space_distance;
  559. typedef T ElementType;
  560. typedef int ResultType;
  561. typedef ElementType CentersType;
  562. /** This is popcount_3() from:
  563. * http://en.wikipedia.org/wiki/Hamming_weight */
  564. unsigned int popcnt32(uint32_t n) const
  565. {
  566. n -= ((n >> 1) & 0x55555555);
  567. n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
  568. return (((n + (n >> 4))& 0xF0F0F0F)* 0x1010101) >> 24;
  569. }
  570. #ifdef FLANN_PLATFORM_64_BIT
  571. unsigned int popcnt64(uint64_t n) const
  572. {
  573. n -= ((n >> 1) & 0x5555555555555555);
  574. n = (n & 0x3333333333333333) + ((n >> 2) & 0x3333333333333333);
  575. return (((n + (n >> 4))& 0x0f0f0f0f0f0f0f0f)* 0x0101010101010101) >> 56;
  576. }
  577. #endif
  578. template <typename Iterator1, typename Iterator2>
  579. ResultType operator()(const Iterator1 a, const Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
  580. {
  581. CV_DbgAssert(!(size % long_word_size_) && "vectors size must be multiple of long words size (i.e. 8)");
  582. #ifdef FLANN_PLATFORM_64_BIT
  583. const uint64_t* pa = reinterpret_cast<const uint64_t*>(a);
  584. const uint64_t* pb = reinterpret_cast<const uint64_t*>(b);
  585. ResultType result = 0;
  586. size /= long_word_size_;
  587. for(size_t i = 0; i < size; ++i ) {
  588. result += popcnt64(*pa ^ *pb);
  589. ++pa;
  590. ++pb;
  591. }
  592. #else
  593. const uint32_t* pa = reinterpret_cast<const uint32_t*>(a);
  594. const uint32_t* pb = reinterpret_cast<const uint32_t*>(b);
  595. ResultType result = 0;
  596. size /= long_word_size_;
  597. for(size_t i = 0; i < size; ++i ) {
  598. result += popcnt32(*pa ^ *pb);
  599. ++pa;
  600. ++pb;
  601. }
  602. #endif
  603. return result;
  604. }
  605. template <typename Iterator1>
  606. ResultType operator()(const Iterator1 a, ZeroIterator<unsigned char> b, size_t size, ResultType /*worst_dist*/ = -1) const
  607. {
  608. CV_DbgAssert(!(size % long_word_size_) && "vectors size must be multiple of long words size (i.e. 8)");
  609. (void)b;
  610. #ifdef FLANN_PLATFORM_64_BIT
  611. const uint64_t* pa = reinterpret_cast<const uint64_t*>(a);
  612. ResultType result = 0;
  613. size /= long_word_size_;
  614. for(size_t i = 0; i < size; ++i ) {
  615. result += popcnt64(*pa);
  616. ++pa;
  617. }
  618. #else
  619. const uint32_t* pa = reinterpret_cast<const uint32_t*>(a);
  620. ResultType result = 0;
  621. size /= long_word_size_;
  622. for(size_t i = 0; i < size; ++i ) {
  623. result += popcnt32(*pa);
  624. ++pa;
  625. }
  626. #endif
  627. return result;
  628. }
  629. private:
  630. #ifdef FLANN_PLATFORM_64_BIT
  631. static const size_t long_word_size_ = sizeof(uint64_t)/sizeof(unsigned char);
  632. #else
  633. static const size_t long_word_size_ = sizeof(uint32_t)/sizeof(unsigned char);
  634. #endif
  635. };
  636. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  637. struct DNAmmingLUT
  638. {
  639. typedef False is_kdtree_distance;
  640. typedef False is_vector_space_distance;
  641. typedef unsigned char ElementType;
  642. typedef int ResultType;
  643. typedef ElementType CentersType;
  644. /** this will count the bits in a ^ b
  645. */
  646. template<typename Iterator2>
  647. ResultType operator()(const unsigned char* a, const Iterator2 b, size_t size) const
  648. {
  649. static const uchar popCountTable[] =
  650. {
  651. 0, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3,
  652. 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3,
  653. 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
  654. 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
  655. 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
  656. 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
  657. 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
  658. 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4
  659. };
  660. ResultType result = 0;
  661. const unsigned char* b2 = reinterpret_cast<const unsigned char*> (b);
  662. for (size_t i = 0; i < size; i++) {
  663. result += popCountTable[a[i] ^ b2[i]];
  664. }
  665. return result;
  666. }
  667. ResultType operator()(const unsigned char* a, const ZeroIterator<unsigned char> b, size_t size) const
  668. {
  669. (void)b;
  670. static const uchar popCountTable[] =
  671. {
  672. 0, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3,
  673. 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3,
  674. 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
  675. 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
  676. 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
  677. 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
  678. 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
  679. 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4
  680. };
  681. ResultType result = 0;
  682. for (size_t i = 0; i < size; i++) {
  683. result += popCountTable[a[i]];
  684. }
  685. return result;
  686. }
  687. };
  688. template<typename T>
  689. struct DNAmming2
  690. {
  691. typedef False is_kdtree_distance;
  692. typedef False is_vector_space_distance;
  693. typedef T ElementType;
  694. typedef int ResultType;
  695. typedef ElementType CentersType;
  696. /** This is popcount_3() from:
  697. * http://en.wikipedia.org/wiki/Hamming_weight */
  698. unsigned int popcnt32(uint32_t n) const
  699. {
  700. n = ((n >> 1) | n) & 0x55555555;
  701. n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
  702. return (((n + (n >> 4))& 0x0F0F0F0F)* 0x01010101) >> 24;
  703. }
  704. #ifdef FLANN_PLATFORM_64_BIT
  705. unsigned int popcnt64(uint64_t n) const
  706. {
  707. n = ((n >> 1) | n) & 0x5555555555555555;
  708. n = (n & 0x3333333333333333) + ((n >> 2) & 0x3333333333333333);
  709. return (((n + (n >> 4))& 0x0f0f0f0f0f0f0f0f)* 0x0101010101010101) >> 56;
  710. }
  711. #endif
  712. template <typename Iterator1, typename Iterator2>
  713. ResultType operator()(const Iterator1 a, const Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
  714. {
  715. CV_DbgAssert(!(size % long_word_size_) && "vectors size must be multiple of long words size (i.e. 8)");
  716. #ifdef FLANN_PLATFORM_64_BIT
  717. const uint64_t* pa = reinterpret_cast<const uint64_t*>(a);
  718. const uint64_t* pb = reinterpret_cast<const uint64_t*>(b);
  719. ResultType result = 0;
  720. size /= long_word_size_;
  721. for(size_t i = 0; i < size; ++i ) {
  722. result += popcnt64(*pa ^ *pb);
  723. ++pa;
  724. ++pb;
  725. }
  726. #else
  727. const uint32_t* pa = reinterpret_cast<const uint32_t*>(a);
  728. const uint32_t* pb = reinterpret_cast<const uint32_t*>(b);
  729. ResultType result = 0;
  730. size /= long_word_size_;
  731. for(size_t i = 0; i < size; ++i ) {
  732. result += popcnt32(*pa ^ *pb);
  733. ++pa;
  734. ++pb;
  735. }
  736. #endif
  737. return result;
  738. }
  739. template <typename Iterator1>
  740. ResultType operator()(const Iterator1 a, ZeroIterator<unsigned char> b, size_t size, ResultType /*worst_dist*/ = -1) const
  741. {
  742. CV_DbgAssert(!(size % long_word_size_) && "vectors size must be multiple of long words size (i.e. 8)");
  743. (void)b;
  744. #ifdef FLANN_PLATFORM_64_BIT
  745. const uint64_t* pa = reinterpret_cast<const uint64_t*>(a);
  746. ResultType result = 0;
  747. size /= long_word_size_;
  748. for(size_t i = 0; i < size; ++i ) {
  749. result += popcnt64(*pa);
  750. ++pa;
  751. }
  752. #else
  753. const uint32_t* pa = reinterpret_cast<const uint32_t*>(a);
  754. ResultType result = 0;
  755. size /= long_word_size_;
  756. for(size_t i = 0; i < size; ++i ) {
  757. result += popcnt32(*pa);
  758. ++pa;
  759. }
  760. #endif
  761. return result;
  762. }
  763. private:
  764. #ifdef FLANN_PLATFORM_64_BIT
  765. static const size_t long_word_size_= sizeof(uint64_t)/sizeof(unsigned char);
  766. #else
  767. static const size_t long_word_size_= sizeof(uint32_t)/sizeof(unsigned char);
  768. #endif
  769. };
  770. template<class T>
  771. struct HistIntersectionDistance
  772. {
  773. typedef True is_kdtree_distance;
  774. typedef True is_vector_space_distance;
  775. typedef T ElementType;
  776. typedef typename Accumulator<T>::Type ResultType;
  777. typedef ResultType CentersType;
  778. /**
  779. * Compute the histogram intersection distance
  780. */
  781. template <typename Iterator1, typename Iterator2>
  782. ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
  783. {
  784. ResultType result = ResultType();
  785. ResultType min0, min1, min2, min3;
  786. Iterator1 last = a + size;
  787. Iterator1 lastgroup = last - 3;
  788. /* Process 4 items with each loop for efficiency. */
  789. while (a < lastgroup) {
  790. min0 = (ResultType)(a[0] < b[0] ? a[0] : b[0]);
  791. min1 = (ResultType)(a[1] < b[1] ? a[1] : b[1]);
  792. min2 = (ResultType)(a[2] < b[2] ? a[2] : b[2]);
  793. min3 = (ResultType)(a[3] < b[3] ? a[3] : b[3]);
  794. result += min0 + min1 + min2 + min3;
  795. a += 4;
  796. b += 4;
  797. if ((worst_dist>0)&&(result>worst_dist)) {
  798. return result;
  799. }
  800. }
  801. /* Process last 0-3 pixels. Not needed for standard vector lengths. */
  802. while (a < last) {
  803. min0 = (ResultType)(*a < *b ? *a : *b);
  804. result += min0;
  805. ++a;
  806. ++b;
  807. }
  808. return result;
  809. }
  810. /**
  811. * Partial distance, used by the kd-tree.
  812. */
  813. template <typename U, typename V>
  814. inline ResultType accum_dist(const U& a, const V& b, int) const
  815. {
  816. return a<b ? a : b;
  817. }
  818. };
  819. template<class T>
  820. struct HellingerDistance
  821. {
  822. typedef True is_kdtree_distance;
  823. typedef True is_vector_space_distance;
  824. typedef T ElementType;
  825. typedef typename Accumulator<T>::Type ResultType;
  826. typedef ResultType CentersType;
  827. /**
  828. * Compute the Hellinger distance
  829. */
  830. template <typename Iterator1, typename Iterator2>
  831. ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
  832. {
  833. ResultType result = ResultType();
  834. ResultType diff0, diff1, diff2, diff3;
  835. Iterator1 last = a + size;
  836. Iterator1 lastgroup = last - 3;
  837. /* Process 4 items with each loop for efficiency. */
  838. while (a < lastgroup) {
  839. diff0 = sqrt(static_cast<ResultType>(a[0])) - sqrt(static_cast<ResultType>(b[0]));
  840. diff1 = sqrt(static_cast<ResultType>(a[1])) - sqrt(static_cast<ResultType>(b[1]));
  841. diff2 = sqrt(static_cast<ResultType>(a[2])) - sqrt(static_cast<ResultType>(b[2]));
  842. diff3 = sqrt(static_cast<ResultType>(a[3])) - sqrt(static_cast<ResultType>(b[3]));
  843. result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
  844. a += 4;
  845. b += 4;
  846. }
  847. while (a < last) {
  848. diff0 = sqrt(static_cast<ResultType>(*a++)) - sqrt(static_cast<ResultType>(*b++));
  849. result += diff0 * diff0;
  850. }
  851. return result;
  852. }
  853. /**
  854. * Partial distance, used by the kd-tree.
  855. */
  856. template <typename U, typename V>
  857. inline ResultType accum_dist(const U& a, const V& b, int) const
  858. {
  859. ResultType diff = sqrt(static_cast<ResultType>(a)) - sqrt(static_cast<ResultType>(b));
  860. return diff * diff;
  861. }
  862. };
  863. template<class T>
  864. struct ChiSquareDistance
  865. {
  866. typedef True is_kdtree_distance;
  867. typedef True is_vector_space_distance;
  868. typedef T ElementType;
  869. typedef typename Accumulator<T>::Type ResultType;
  870. typedef ResultType CentersType;
  871. /**
  872. * Compute the chi-square distance
  873. */
  874. template <typename Iterator1, typename Iterator2>
  875. ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
  876. {
  877. ResultType result = ResultType();
  878. ResultType sum, diff;
  879. Iterator1 last = a + size;
  880. while (a < last) {
  881. sum = (ResultType)(*a + *b);
  882. if (sum>0) {
  883. diff = (ResultType)(*a - *b);
  884. result += diff*diff/sum;
  885. }
  886. ++a;
  887. ++b;
  888. if ((worst_dist>0)&&(result>worst_dist)) {
  889. return result;
  890. }
  891. }
  892. return result;
  893. }
  894. /**
  895. * Partial distance, used by the kd-tree.
  896. */
  897. template <typename U, typename V>
  898. inline ResultType accum_dist(const U& a, const V& b, int) const
  899. {
  900. ResultType result = ResultType();
  901. ResultType sum, diff;
  902. sum = (ResultType)(a+b);
  903. if (sum>0) {
  904. diff = (ResultType)(a-b);
  905. result = diff*diff/sum;
  906. }
  907. return result;
  908. }
  909. };
  910. template<class T>
  911. struct KL_Divergence
  912. {
  913. typedef True is_kdtree_distance;
  914. typedef True is_vector_space_distance;
  915. typedef T ElementType;
  916. typedef typename Accumulator<T>::Type ResultType;
  917. typedef ResultType CentersType;
  918. /**
  919. * Compute the Kullback-Leibler divergence
  920. */
  921. template <typename Iterator1, typename Iterator2>
  922. ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
  923. {
  924. ResultType result = ResultType();
  925. Iterator1 last = a + size;
  926. while (a < last) {
  927. if ( *a != 0 && *b != 0 ) {
  928. ResultType ratio = (ResultType)(*a / *b);
  929. if (ratio>0) {
  930. result += *a * log(ratio);
  931. }
  932. }
  933. ++a;
  934. ++b;
  935. if ((worst_dist>0)&&(result>worst_dist)) {
  936. return result;
  937. }
  938. }
  939. return result;
  940. }
  941. /**
  942. * Partial distance, used by the kd-tree.
  943. */
  944. template <typename U, typename V>
  945. inline ResultType accum_dist(const U& a, const V& b, int) const
  946. {
  947. ResultType result = ResultType();
  948. if( a != 0 && b != 0 ) {
  949. ResultType ratio = (ResultType)(a / b);
  950. if (ratio>0) {
  951. result = a * log(ratio);
  952. }
  953. }
  954. return result;
  955. }
  956. };
  957. /*
  958. * Depending on processed distances, some of them are already squared (e.g. L2)
  959. * and some are not (e.g.Hamming). In KMeans++ for instance we want to be sure
  960. * we are working on ^2 distances, thus following templates to ensure that.
  961. */
  962. template <typename Distance, typename ElementType>
  963. struct squareDistance
  964. {
  965. typedef typename Distance::ResultType ResultType;
  966. ResultType operator()( ResultType dist ) { return dist*dist; }
  967. };
  968. template <typename ElementType>
  969. struct squareDistance<L2_Simple<ElementType>, ElementType>
  970. {
  971. typedef typename L2_Simple<ElementType>::ResultType ResultType;
  972. ResultType operator()( ResultType dist ) { return dist; }
  973. };
  974. template <typename ElementType>
  975. struct squareDistance<L2<ElementType>, ElementType>
  976. {
  977. typedef typename L2<ElementType>::ResultType ResultType;
  978. ResultType operator()( ResultType dist ) { return dist; }
  979. };
  980. template <typename ElementType>
  981. struct squareDistance<MinkowskiDistance<ElementType>, ElementType>
  982. {
  983. typedef typename MinkowskiDistance<ElementType>::ResultType ResultType;
  984. ResultType operator()( ResultType dist ) { return dist; }
  985. };
  986. template <typename ElementType>
  987. struct squareDistance<HellingerDistance<ElementType>, ElementType>
  988. {
  989. typedef typename HellingerDistance<ElementType>::ResultType ResultType;
  990. ResultType operator()( ResultType dist ) { return dist; }
  991. };
  992. template <typename ElementType>
  993. struct squareDistance<ChiSquareDistance<ElementType>, ElementType>
  994. {
  995. typedef typename ChiSquareDistance<ElementType>::ResultType ResultType;
  996. ResultType operator()( ResultType dist ) { return dist; }
  997. };
  998. template <typename Distance>
  999. typename Distance::ResultType ensureSquareDistance( typename Distance::ResultType dist )
  1000. {
  1001. typedef typename Distance::ElementType ElementType;
  1002. squareDistance<Distance, ElementType> dummy;
  1003. return dummy( dist );
  1004. }
  1005. /*
  1006. * ...a template to tell the user if the distance he is working with is actually squared
  1007. */
  1008. template <typename Distance, typename ElementType>
  1009. struct isSquareDist
  1010. {
  1011. bool operator()() { return false; }
  1012. };
  1013. template <typename ElementType>
  1014. struct isSquareDist<L2_Simple<ElementType>, ElementType>
  1015. {
  1016. bool operator()() { return true; }
  1017. };
  1018. template <typename ElementType>
  1019. struct isSquareDist<L2<ElementType>, ElementType>
  1020. {
  1021. bool operator()() { return true; }
  1022. };
  1023. template <typename ElementType>
  1024. struct isSquareDist<MinkowskiDistance<ElementType>, ElementType>
  1025. {
  1026. bool operator()() { return true; }
  1027. };
  1028. template <typename ElementType>
  1029. struct isSquareDist<HellingerDistance<ElementType>, ElementType>
  1030. {
  1031. bool operator()() { return true; }
  1032. };
  1033. template <typename ElementType>
  1034. struct isSquareDist<ChiSquareDistance<ElementType>, ElementType>
  1035. {
  1036. bool operator()() { return true; }
  1037. };
  1038. template <typename Distance>
  1039. bool isSquareDistance()
  1040. {
  1041. typedef typename Distance::ElementType ElementType;
  1042. isSquareDist<Distance, ElementType> dummy;
  1043. return dummy();
  1044. }
  1045. /*
  1046. * ...and a template to ensure the user that he will process the normal distance,
  1047. * and not squared distance, without losing processing time calling sqrt(ensureSquareDistance)
  1048. * that will result in doing actually sqrt(dist*dist) for L1 distance for instance.
  1049. */
  1050. template <typename Distance, typename ElementType>
  1051. struct simpleDistance
  1052. {
  1053. typedef typename Distance::ResultType ResultType;
  1054. ResultType operator()( ResultType dist ) { return dist; }
  1055. };
  1056. template <typename ElementType>
  1057. struct simpleDistance<L2_Simple<ElementType>, ElementType>
  1058. {
  1059. typedef typename L2_Simple<ElementType>::ResultType ResultType;
  1060. ResultType operator()( ResultType dist ) { return sqrt(dist); }
  1061. };
  1062. template <typename ElementType>
  1063. struct simpleDistance<L2<ElementType>, ElementType>
  1064. {
  1065. typedef typename L2<ElementType>::ResultType ResultType;
  1066. ResultType operator()( ResultType dist ) { return sqrt(dist); }
  1067. };
  1068. template <typename ElementType>
  1069. struct simpleDistance<MinkowskiDistance<ElementType>, ElementType>
  1070. {
  1071. typedef typename MinkowskiDistance<ElementType>::ResultType ResultType;
  1072. ResultType operator()( ResultType dist ) { return sqrt(dist); }
  1073. };
  1074. template <typename ElementType>
  1075. struct simpleDistance<HellingerDistance<ElementType>, ElementType>
  1076. {
  1077. typedef typename HellingerDistance<ElementType>::ResultType ResultType;
  1078. ResultType operator()( ResultType dist ) { return sqrt(dist); }
  1079. };
  1080. template <typename ElementType>
  1081. struct simpleDistance<ChiSquareDistance<ElementType>, ElementType>
  1082. {
  1083. typedef typename ChiSquareDistance<ElementType>::ResultType ResultType;
  1084. ResultType operator()( ResultType dist ) { return sqrt(dist); }
  1085. };
  1086. template <typename Distance>
  1087. typename Distance::ResultType ensureSimpleDistance( typename Distance::ResultType dist )
  1088. {
  1089. typedef typename Distance::ElementType ElementType;
  1090. simpleDistance<Distance, ElementType> dummy;
  1091. return dummy( dist );
  1092. }
  1093. }
  1094. //! @endcond
  1095. #endif //OPENCV_FLANN_DIST_H_