openCV library for Renesas RZ/A

Dependents:   RZ_A2M_Mbed_samples

Committer:
RyoheiHagimoto
Date:
Fri Jan 29 04:53:38 2021 +0000
Revision:
0:0e0631af0305
copied from https://github.com/d-kato/opencv-lib.

Who changed what in which revision?

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