正在显示
15 个修改的文件
包含
4390 行增加
和
0 行删除
| 1 | +/*M/////////////////////////////////////////////////////////////////////////////////////// | ||
| 2 | +// | ||
| 3 | +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. | ||
| 4 | +// | ||
| 5 | +// By downloading, copying, installing or using the software you agree to this license. | ||
| 6 | +// If you do not agree to this license, do not download, install, | ||
| 7 | +// copy or use the software. | ||
| 8 | +// | ||
| 9 | +// | ||
| 10 | +// License Agreement | ||
| 11 | +// For Open Source Computer Vision Library | ||
| 12 | +// | ||
| 13 | +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. | ||
| 14 | +// Third party copyrights are property of their respective owners. | ||
| 15 | +// | ||
| 16 | +// Redistribution and use in source and binary forms, with or without modification, | ||
| 17 | +// are permitted provided that the following conditions are met: | ||
| 18 | +// | ||
| 19 | +// * Redistribution's of source code must retain the above copyright notice, | ||
| 20 | +// this list of conditions and the following disclaimer. | ||
| 21 | +// | ||
| 22 | +// * Redistribution's in binary form must reproduce the above copyright notice, | ||
| 23 | +// this list of conditions and the following disclaimer in the documentation | ||
| 24 | +// and/or other materials provided with the distribution. | ||
| 25 | +// | ||
| 26 | +// * The name of the copyright holders may not be used to endorse or promote products | ||
| 27 | +// derived from this software without specific prior written permission. | ||
| 28 | +// | ||
| 29 | +// This software is provided by the copyright holders and contributors "as is" and | ||
| 30 | +// any express or implied warranties, including, but not limited to, the implied | ||
| 31 | +// warranties of merchantability and fitness for a particular purpose are disclaimed. | ||
| 32 | +// In no event shall the Intel Corporation or contributors be liable for any direct, | ||
| 33 | +// indirect, incidental, special, exemplary, or consequential damages | ||
| 34 | +// (including, but not limited to, procurement of substitute goods or services; | ||
| 35 | +// loss of use, data, or profits; or business interruption) however caused | ||
| 36 | +// and on any theory of liability, whether in contract, strict liability, | ||
| 37 | +// or tort (including negligence or otherwise) arising in any way out of | ||
| 38 | +// the use of this software, even if advised of the possibility of such damage. | ||
| 39 | +// | ||
| 40 | +//M*/ | ||
| 41 | + | ||
| 42 | +#ifndef OPENCV_DNN_LAYER_HPP | ||
| 43 | +#define OPENCV_DNN_LAYER_HPP | ||
| 44 | +#include <opencv2/dnn.hpp> | ||
| 45 | + | ||
| 46 | +namespace cv { | ||
| 47 | +namespace dnn { | ||
| 48 | +CV__DNN_INLINE_NS_BEGIN | ||
| 49 | +//! @addtogroup dnn | ||
| 50 | +//! @{ | ||
| 51 | +//! | ||
| 52 | +//! @defgroup dnnLayerFactory Utilities for New Layers Registration | ||
| 53 | +//! @{ | ||
| 54 | + | ||
| 55 | +/** @brief %Layer factory allows to create instances of registered layers. */ | ||
| 56 | +class CV_EXPORTS LayerFactory | ||
| 57 | +{ | ||
| 58 | +public: | ||
| 59 | + | ||
| 60 | + //! Each Layer class must provide this function to the factory | ||
| 61 | + typedef Ptr<Layer>(*Constructor)(LayerParams ¶ms); | ||
| 62 | + | ||
| 63 | + //! Registers the layer class with typename @p type and specified @p constructor. Thread-safe. | ||
| 64 | + static void registerLayer(const String &type, Constructor constructor); | ||
| 65 | + | ||
| 66 | + //! Unregisters registered layer with specified type name. Thread-safe. | ||
| 67 | + static void unregisterLayer(const String &type); | ||
| 68 | + | ||
| 69 | + /** @brief Creates instance of registered layer. | ||
| 70 | + * @param type type name of creating layer. | ||
| 71 | + * @param params parameters which will be used for layer initialization. | ||
| 72 | + * @note Thread-safe. | ||
| 73 | + */ | ||
| 74 | + static Ptr<Layer> createLayerInstance(const String &type, LayerParams& params); | ||
| 75 | + | ||
| 76 | +private: | ||
| 77 | + LayerFactory(); | ||
| 78 | +}; | ||
| 79 | + | ||
| 80 | +//! @} | ||
| 81 | +//! @} | ||
| 82 | +CV__DNN_INLINE_NS_END | ||
| 83 | +} | ||
| 84 | +} | ||
| 85 | +#endif |
| 1 | +/*M/////////////////////////////////////////////////////////////////////////////////////// | ||
| 2 | +// | ||
| 3 | +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. | ||
| 4 | +// | ||
| 5 | +// By downloading, copying, installing or using the software you agree to this license. | ||
| 6 | +// If you do not agree to this license, do not download, install, | ||
| 7 | +// copy or use the software. | ||
| 8 | +// | ||
| 9 | +// | ||
| 10 | +// License Agreement | ||
| 11 | +// For Open Source Computer Vision Library | ||
| 12 | +// | ||
| 13 | +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. | ||
| 14 | +// Third party copyrights are property of their respective owners. | ||
| 15 | +// | ||
| 16 | +// Redistribution and use in source and binary forms, with or without modification, | ||
| 17 | +// are permitted provided that the following conditions are met: | ||
| 18 | +// | ||
| 19 | +// * Redistribution's of source code must retain the above copyright notice, | ||
| 20 | +// this list of conditions and the following disclaimer. | ||
| 21 | +// | ||
| 22 | +// * Redistribution's in binary form must reproduce the above copyright notice, | ||
| 23 | +// this list of conditions and the following disclaimer in the documentation | ||
| 24 | +// and/or other materials provided with the distribution. | ||
| 25 | +// | ||
| 26 | +// * The name of the copyright holders may not be used to endorse or promote products | ||
| 27 | +// derived from this software without specific prior written permission. | ||
| 28 | +// | ||
| 29 | +// This software is provided by the copyright holders and contributors "as is" and | ||
| 30 | +// any express or implied warranties, including, but not limited to, the implied | ||
| 31 | +// warranties of merchantability and fitness for a particular purpose are disclaimed. | ||
| 32 | +// In no event shall the Intel Corporation or contributors be liable for any direct, | ||
| 33 | +// indirect, incidental, special, exemplary, or consequential damages | ||
| 34 | +// (including, but not limited to, procurement of substitute goods or services; | ||
| 35 | +// loss of use, data, or profits; or business interruption) however caused | ||
| 36 | +// and on any theory of liability, whether in contract, strict liability, | ||
| 37 | +// or tort (including negligence or otherwise) arising in any way out of | ||
| 38 | +// the use of this software, even if advised of the possibility of such damage. | ||
| 39 | +// | ||
| 40 | +//M*/ | ||
| 41 | + | ||
| 42 | +#ifndef OPENCV_DNN_DNN_SHAPE_UTILS_HPP | ||
| 43 | +#define OPENCV_DNN_DNN_SHAPE_UTILS_HPP | ||
| 44 | + | ||
| 45 | +#include <opencv2/dnn/dnn.hpp> | ||
| 46 | +#include <opencv2/core/types_c.h> // CV_MAX_DIM | ||
| 47 | +#include <iostream> | ||
| 48 | +#include <ostream> | ||
| 49 | +#include <sstream> | ||
| 50 | + | ||
| 51 | +namespace cv { | ||
| 52 | +namespace dnn { | ||
| 53 | +CV__DNN_INLINE_NS_BEGIN | ||
| 54 | + | ||
| 55 | +//Slicing | ||
| 56 | + | ||
| 57 | +struct _Range : public cv::Range | ||
| 58 | +{ | ||
| 59 | + _Range(const Range &r) : cv::Range(r) {} | ||
| 60 | + _Range(int start_, int size_ = 1) : cv::Range(start_, start_ + size_) {} | ||
| 61 | +}; | ||
| 62 | + | ||
| 63 | +static inline Mat slice(const Mat &m, const _Range &r0) | ||
| 64 | +{ | ||
| 65 | + Range ranges[CV_MAX_DIM]; | ||
| 66 | + for (int i = 1; i < m.dims; i++) | ||
| 67 | + ranges[i] = Range::all(); | ||
| 68 | + ranges[0] = r0; | ||
| 69 | + return m(&ranges[0]); | ||
| 70 | +} | ||
| 71 | + | ||
| 72 | +static inline Mat slice(const Mat &m, const _Range &r0, const _Range &r1) | ||
| 73 | +{ | ||
| 74 | + CV_Assert(m.dims >= 2); | ||
| 75 | + Range ranges[CV_MAX_DIM]; | ||
| 76 | + for (int i = 2; i < m.dims; i++) | ||
| 77 | + ranges[i] = Range::all(); | ||
| 78 | + ranges[0] = r0; | ||
| 79 | + ranges[1] = r1; | ||
| 80 | + return m(&ranges[0]); | ||
| 81 | +} | ||
| 82 | + | ||
| 83 | +static inline Mat slice(const Mat &m, const _Range &r0, const _Range &r1, const _Range &r2) | ||
| 84 | +{ | ||
| 85 | + CV_Assert(m.dims >= 3); | ||
| 86 | + Range ranges[CV_MAX_DIM]; | ||
| 87 | + for (int i = 3; i < m.dims; i++) | ||
| 88 | + ranges[i] = Range::all(); | ||
| 89 | + ranges[0] = r0; | ||
| 90 | + ranges[1] = r1; | ||
| 91 | + ranges[2] = r2; | ||
| 92 | + return m(&ranges[0]); | ||
| 93 | +} | ||
| 94 | + | ||
| 95 | +static inline Mat slice(const Mat &m, const _Range &r0, const _Range &r1, const _Range &r2, const _Range &r3) | ||
| 96 | +{ | ||
| 97 | + CV_Assert(m.dims >= 4); | ||
| 98 | + Range ranges[CV_MAX_DIM]; | ||
| 99 | + for (int i = 4; i < m.dims; i++) | ||
| 100 | + ranges[i] = Range::all(); | ||
| 101 | + ranges[0] = r0; | ||
| 102 | + ranges[1] = r1; | ||
| 103 | + ranges[2] = r2; | ||
| 104 | + ranges[3] = r3; | ||
| 105 | + return m(&ranges[0]); | ||
| 106 | +} | ||
| 107 | + | ||
| 108 | +static inline Mat getPlane(const Mat &m, int n, int cn) | ||
| 109 | +{ | ||
| 110 | + CV_Assert(m.dims > 2); | ||
| 111 | + int sz[CV_MAX_DIM]; | ||
| 112 | + for(int i = 2; i < m.dims; i++) | ||
| 113 | + { | ||
| 114 | + sz[i-2] = m.size.p[i]; | ||
| 115 | + } | ||
| 116 | + return Mat(m.dims - 2, sz, m.type(), (void*)m.ptr<float>(n, cn)); | ||
| 117 | +} | ||
| 118 | + | ||
| 119 | +static inline MatShape shape(const int* dims, const int n) | ||
| 120 | +{ | ||
| 121 | + MatShape shape; | ||
| 122 | + shape.assign(dims, dims + n); | ||
| 123 | + return shape; | ||
| 124 | +} | ||
| 125 | + | ||
| 126 | +static inline MatShape shape(const Mat& mat) | ||
| 127 | +{ | ||
| 128 | + return shape(mat.size.p, mat.dims); | ||
| 129 | +} | ||
| 130 | + | ||
| 131 | +static inline MatShape shape(const MatSize& sz) | ||
| 132 | +{ | ||
| 133 | + return shape(sz.p, sz.dims()); | ||
| 134 | +} | ||
| 135 | + | ||
| 136 | +static inline MatShape shape(const UMat& mat) | ||
| 137 | +{ | ||
| 138 | + return shape(mat.size.p, mat.dims); | ||
| 139 | +} | ||
| 140 | + | ||
| 141 | +#if 0 // issues with MatExpr wrapped into InputArray | ||
| 142 | +static inline | ||
| 143 | +MatShape shape(InputArray input) | ||
| 144 | +{ | ||
| 145 | + int sz[CV_MAX_DIM]; | ||
| 146 | + int ndims = input.sizend(sz); | ||
| 147 | + return shape(sz, ndims); | ||
| 148 | +} | ||
| 149 | +#endif | ||
| 150 | + | ||
| 151 | +namespace {inline bool is_neg(int i) { return i < 0; }} | ||
| 152 | + | ||
| 153 | +static inline MatShape shape(int a0, int a1=-1, int a2=-1, int a3=-1) | ||
| 154 | +{ | ||
| 155 | + int dims[] = {a0, a1, a2, a3}; | ||
| 156 | + MatShape s = shape(dims, 4); | ||
| 157 | + s.erase(std::remove_if(s.begin(), s.end(), is_neg), s.end()); | ||
| 158 | + return s; | ||
| 159 | +} | ||
| 160 | + | ||
| 161 | +static inline int total(const MatShape& shape, int start = -1, int end = -1) | ||
| 162 | +{ | ||
| 163 | + if (start == -1) start = 0; | ||
| 164 | + if (end == -1) end = (int)shape.size(); | ||
| 165 | + | ||
| 166 | + if (shape.empty()) | ||
| 167 | + return 0; | ||
| 168 | + | ||
| 169 | + int elems = 1; | ||
| 170 | + CV_Assert(start <= (int)shape.size() && end <= (int)shape.size() && | ||
| 171 | + start <= end); | ||
| 172 | + for(int i = start; i < end; i++) | ||
| 173 | + { | ||
| 174 | + elems *= shape[i]; | ||
| 175 | + } | ||
| 176 | + return elems; | ||
| 177 | +} | ||
| 178 | + | ||
| 179 | +static inline MatShape concat(const MatShape& a, const MatShape& b) | ||
| 180 | +{ | ||
| 181 | + MatShape c = a; | ||
| 182 | + c.insert(c.end(), b.begin(), b.end()); | ||
| 183 | + | ||
| 184 | + return c; | ||
| 185 | +} | ||
| 186 | + | ||
| 187 | +static inline std::string toString(const MatShape& shape, const String& name = "") | ||
| 188 | +{ | ||
| 189 | + std::ostringstream ss; | ||
| 190 | + if (!name.empty()) | ||
| 191 | + ss << name << ' '; | ||
| 192 | + ss << '['; | ||
| 193 | + for(size_t i = 0, n = shape.size(); i < n; ++i) | ||
| 194 | + ss << ' ' << shape[i]; | ||
| 195 | + ss << " ]"; | ||
| 196 | + return ss.str(); | ||
| 197 | +} | ||
| 198 | +static inline void print(const MatShape& shape, const String& name = "") | ||
| 199 | +{ | ||
| 200 | + std::cout << toString(shape, name) << std::endl; | ||
| 201 | +} | ||
| 202 | +static inline std::ostream& operator<<(std::ostream &out, const MatShape& shape) | ||
| 203 | +{ | ||
| 204 | + out << toString(shape); | ||
| 205 | + return out; | ||
| 206 | +} | ||
| 207 | + | ||
| 208 | +/// @brief Converts axis from `[-dims; dims)` (similar to Python's slice notation) to `[0; dims)` range. | ||
| 209 | +static inline | ||
| 210 | +int normalize_axis(int axis, int dims) | ||
| 211 | +{ | ||
| 212 | + CV_Check(axis, axis >= -dims && axis < dims, ""); | ||
| 213 | + axis = (axis < 0) ? (dims + axis) : axis; | ||
| 214 | + CV_DbgCheck(axis, axis >= 0 && axis < dims, ""); | ||
| 215 | + return axis; | ||
| 216 | +} | ||
| 217 | + | ||
| 218 | +static inline | ||
| 219 | +int normalize_axis(int axis, const MatShape& shape) | ||
| 220 | +{ | ||
| 221 | + return normalize_axis(axis, (int)shape.size()); | ||
| 222 | +} | ||
| 223 | + | ||
| 224 | +static inline | ||
| 225 | +Range normalize_axis_range(const Range& r, int axisSize) | ||
| 226 | +{ | ||
| 227 | + if (r == Range::all()) | ||
| 228 | + return Range(0, axisSize); | ||
| 229 | + CV_CheckGE(r.start, 0, ""); | ||
| 230 | + Range clamped(r.start, | ||
| 231 | + r.end > 0 ? std::min(r.end, axisSize) : axisSize + r.end + 1); | ||
| 232 | + CV_DbgCheckGE(clamped.start, 0, ""); | ||
| 233 | + CV_CheckLT(clamped.start, clamped.end, ""); | ||
| 234 | + CV_CheckLE(clamped.end, axisSize, ""); | ||
| 235 | + return clamped; | ||
| 236 | +} | ||
| 237 | + | ||
| 238 | +static inline | ||
| 239 | +bool isAllOnes(const MatShape &inputShape, int startPos, int endPos) | ||
| 240 | +{ | ||
| 241 | + CV_Assert(!inputShape.empty()); | ||
| 242 | + | ||
| 243 | + CV_CheckGE((int) inputShape.size(), startPos, ""); | ||
| 244 | + CV_CheckGE(startPos, 0, ""); | ||
| 245 | + CV_CheckLE(startPos, endPos, ""); | ||
| 246 | + CV_CheckLE((size_t)endPos, inputShape.size(), ""); | ||
| 247 | + | ||
| 248 | + for (size_t i = startPos; i < endPos; i++) | ||
| 249 | + { | ||
| 250 | + if (inputShape[i] != 1) | ||
| 251 | + return false; | ||
| 252 | + } | ||
| 253 | + return true; | ||
| 254 | +} | ||
| 255 | + | ||
| 256 | +CV__DNN_INLINE_NS_END | ||
| 257 | +} | ||
| 258 | +} | ||
| 259 | +#endif |
| 1 | +// This file is part of OpenCV project. | ||
| 2 | +// It is subject to the license terms in the LICENSE file found in the top-level directory | ||
| 3 | +// of this distribution and at http://opencv.org/license.html. | ||
| 4 | +// | ||
| 5 | +// Copyright (C) 2018-2019, Intel Corporation, all rights reserved. | ||
| 6 | +// Third party copyrights are property of their respective owners. | ||
| 7 | + | ||
| 8 | +#ifndef OPENCV_DNN_UTILS_INF_ENGINE_HPP | ||
| 9 | +#define OPENCV_DNN_UTILS_INF_ENGINE_HPP | ||
| 10 | + | ||
| 11 | +#include "../dnn.hpp" | ||
| 12 | + | ||
| 13 | +namespace cv { namespace dnn { | ||
| 14 | +CV__DNN_INLINE_NS_BEGIN | ||
| 15 | + | ||
| 16 | + | ||
| 17 | +/* Values for 'OPENCV_DNN_BACKEND_INFERENCE_ENGINE_TYPE' parameter */ | ||
| 18 | +#define CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API "NN_BUILDER" | ||
| 19 | +#define CV_DNN_BACKEND_INFERENCE_ENGINE_NGRAPH "NGRAPH" | ||
| 20 | + | ||
| 21 | +/** @brief Returns Inference Engine internal backend API. | ||
| 22 | + * | ||
| 23 | + * See values of `CV_DNN_BACKEND_INFERENCE_ENGINE_*` macros. | ||
| 24 | + * | ||
| 25 | + * Default value is controlled through `OPENCV_DNN_BACKEND_INFERENCE_ENGINE_TYPE` runtime parameter (environment variable). | ||
| 26 | + */ | ||
| 27 | +CV_EXPORTS_W cv::String getInferenceEngineBackendType(); | ||
| 28 | + | ||
| 29 | +/** @brief Specify Inference Engine internal backend API. | ||
| 30 | + * | ||
| 31 | + * See values of `CV_DNN_BACKEND_INFERENCE_ENGINE_*` macros. | ||
| 32 | + * | ||
| 33 | + * @returns previous value of internal backend API | ||
| 34 | + */ | ||
| 35 | +CV_EXPORTS_W cv::String setInferenceEngineBackendType(const cv::String& newBackendType); | ||
| 36 | + | ||
| 37 | + | ||
| 38 | +/** @brief Release a Myriad device (binded by OpenCV). | ||
| 39 | + * | ||
| 40 | + * Single Myriad device cannot be shared across multiple processes which uses | ||
| 41 | + * Inference Engine's Myriad plugin. | ||
| 42 | + */ | ||
| 43 | +CV_EXPORTS_W void resetMyriadDevice(); | ||
| 44 | + | ||
| 45 | + | ||
| 46 | +/* Values for 'OPENCV_DNN_IE_VPU_TYPE' parameter */ | ||
| 47 | +#define CV_DNN_INFERENCE_ENGINE_VPU_TYPE_UNSPECIFIED "" | ||
| 48 | +/// Intel(R) Movidius(TM) Neural Compute Stick, NCS (USB 03e7:2150), Myriad2 (https://software.intel.com/en-us/movidius-ncs) | ||
| 49 | +#define CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2 "Myriad2" | ||
| 50 | +/// Intel(R) Neural Compute Stick 2, NCS2 (USB 03e7:2485), MyriadX (https://software.intel.com/ru-ru/neural-compute-stick) | ||
| 51 | +#define CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X "MyriadX" | ||
| 52 | +#define CV_DNN_INFERENCE_ENGINE_CPU_TYPE_ARM_COMPUTE "ARM_COMPUTE" | ||
| 53 | +#define CV_DNN_INFERENCE_ENGINE_CPU_TYPE_X86 "X86" | ||
| 54 | + | ||
| 55 | + | ||
| 56 | +/** @brief Returns Inference Engine VPU type. | ||
| 57 | + * | ||
| 58 | + * See values of `CV_DNN_INFERENCE_ENGINE_VPU_TYPE_*` macros. | ||
| 59 | + */ | ||
| 60 | +CV_EXPORTS_W cv::String getInferenceEngineVPUType(); | ||
| 61 | + | ||
| 62 | +/** @brief Returns Inference Engine CPU type. | ||
| 63 | + * | ||
| 64 | + * Specify OpenVINO plugin: CPU or ARM. | ||
| 65 | + */ | ||
| 66 | +CV_EXPORTS_W cv::String getInferenceEngineCPUType(); | ||
| 67 | + | ||
| 68 | +/** @brief Release a HDDL plugin. | ||
| 69 | + */ | ||
| 70 | +CV_EXPORTS_W void releaseHDDLPlugin(); | ||
| 71 | + | ||
| 72 | + | ||
| 73 | +CV__DNN_INLINE_NS_END | ||
| 74 | +}} // namespace | ||
| 75 | + | ||
| 76 | +#endif // OPENCV_DNN_UTILS_INF_ENGINE_HPP |
| 1 | +// This file is part of OpenCV project. | ||
| 2 | +// It is subject to the license terms in the LICENSE file found in the top-level directory | ||
| 3 | +// of this distribution and at http://opencv.org/license.html. | ||
| 4 | + | ||
| 5 | +#ifndef OPENCV_DNN_VERSION_HPP | ||
| 6 | +#define OPENCV_DNN_VERSION_HPP | ||
| 7 | + | ||
| 8 | +/// Use with major OpenCV version only. | ||
| 9 | +#define OPENCV_DNN_API_VERSION 20210301 | ||
| 10 | + | ||
| 11 | +#if !defined CV_DOXYGEN && !defined CV_STATIC_ANALYSIS && !defined CV_DNN_DONT_ADD_INLINE_NS | ||
| 12 | +#define CV__DNN_INLINE_NS __CV_CAT(dnn4_v, OPENCV_DNN_API_VERSION) | ||
| 13 | +#define CV__DNN_INLINE_NS_BEGIN namespace CV__DNN_INLINE_NS { | ||
| 14 | +#define CV__DNN_INLINE_NS_END } | ||
| 15 | +namespace cv { namespace dnn { namespace CV__DNN_INLINE_NS { } using namespace CV__DNN_INLINE_NS; }} | ||
| 16 | +#else | ||
| 17 | +#define CV__DNN_INLINE_NS_BEGIN | ||
| 18 | +#define CV__DNN_INLINE_NS_END | ||
| 19 | +#endif | ||
| 20 | + | ||
| 21 | +#endif // OPENCV_DNN_VERSION_HPP |
| 1 | +/*M/////////////////////////////////////////////////////////////////////////////////////// | ||
| 2 | +// | ||
| 3 | +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. | ||
| 4 | +// | ||
| 5 | +// By downloading, copying, installing or using the software you agree to this license. | ||
| 6 | +// If you do not agree to this license, do not download, install, | ||
| 7 | +// copy or use the software. | ||
| 8 | +// | ||
| 9 | +// | ||
| 10 | +// License Agreement | ||
| 11 | +// For Open Source Computer Vision Library | ||
| 12 | +// | ||
| 13 | +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. | ||
| 14 | +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. | ||
| 15 | +// Third party copyrights are property of their respective owners. | ||
| 16 | +// | ||
| 17 | +// Redistribution and use in source and binary forms, with or without modification, | ||
| 18 | +// are permitted provided that the following conditions are met: | ||
| 19 | +// | ||
| 20 | +// * Redistribution's of source code must retain the above copyright notice, | ||
| 21 | +// this list of conditions and the following disclaimer. | ||
| 22 | +// | ||
| 23 | +// * Redistribution's in binary form must reproduce the above copyright notice, | ||
| 24 | +// this list of conditions and the following disclaimer in the documentation | ||
| 25 | +// and/or other materials provided with the distribution. | ||
| 26 | +// | ||
| 27 | +// * The name of the copyright holders may not be used to endorse or promote products | ||
| 28 | +// derived from this software without specific prior written permission. | ||
| 29 | +// | ||
| 30 | +// This software is provided by the copyright holders and contributors "as is" and | ||
| 31 | +// any express or implied warranties, including, but not limited to, the implied | ||
| 32 | +// warranties of merchantability and fitness for a particular purpose are disclaimed. | ||
| 33 | +// In no event shall the Intel Corporation or contributors be liable for any direct, | ||
| 34 | +// indirect, incidental, special, exemplary, or consequential damages | ||
| 35 | +// (including, but not limited to, procurement of substitute goods or services; | ||
| 36 | +// loss of use, data, or profits; or business interruption) however caused | ||
| 37 | +// and on any theory of liability, whether in contract, strict liability, | ||
| 38 | +// or tort (including negligence or otherwise) arising in any way out of | ||
| 39 | +// the use of this software, even if advised of the possibility of such damage. | ||
| 40 | +// | ||
| 41 | +//M*/ | ||
| 42 | + | ||
| 43 | +#ifndef OPENCV_FEATURES_2D_HPP | ||
| 44 | +#define OPENCV_FEATURES_2D_HPP | ||
| 45 | + | ||
| 46 | +#include "opencv2/opencv_modules.hpp" | ||
| 47 | +#include "opencv2/core.hpp" | ||
| 48 | + | ||
| 49 | +#ifdef HAVE_OPENCV_FLANN | ||
| 50 | +#include "opencv2/flann/miniflann.hpp" | ||
| 51 | +#endif | ||
| 52 | + | ||
| 53 | +/** | ||
| 54 | + @defgroup features2d 2D Features Framework | ||
| 55 | + @{ | ||
| 56 | + @defgroup features2d_main Feature Detection and Description | ||
| 57 | + @defgroup features2d_match Descriptor Matchers | ||
| 58 | + | ||
| 59 | +Matchers of keypoint descriptors in OpenCV have wrappers with a common interface that enables you to | ||
| 60 | +easily switch between different algorithms solving the same problem. This section is devoted to | ||
| 61 | +matching descriptors that are represented as vectors in a multidimensional space. All objects that | ||
| 62 | +implement vector descriptor matchers inherit the DescriptorMatcher interface. | ||
| 63 | + | ||
| 64 | +@note | ||
| 65 | + - An example explaining keypoint matching can be found at | ||
| 66 | + opencv_source_code/samples/cpp/descriptor_extractor_matcher.cpp | ||
| 67 | + - An example on descriptor matching evaluation can be found at | ||
| 68 | + opencv_source_code/samples/cpp/detector_descriptor_matcher_evaluation.cpp | ||
| 69 | + - An example on one to many image matching can be found at | ||
| 70 | + opencv_source_code/samples/cpp/matching_to_many_images.cpp | ||
| 71 | + | ||
| 72 | + @defgroup features2d_draw Drawing Function of Keypoints and Matches | ||
| 73 | + @defgroup features2d_category Object Categorization | ||
| 74 | + | ||
| 75 | +This section describes approaches based on local 2D features and used to categorize objects. | ||
| 76 | + | ||
| 77 | +@note | ||
| 78 | + - A complete Bag-Of-Words sample can be found at | ||
| 79 | + opencv_source_code/samples/cpp/bagofwords_classification.cpp | ||
| 80 | + - (Python) An example using the features2D framework to perform object categorization can be | ||
| 81 | + found at opencv_source_code/samples/python/find_obj.py | ||
| 82 | + | ||
| 83 | + @defgroup feature2d_hal Hardware Acceleration Layer | ||
| 84 | + @{ | ||
| 85 | + @defgroup features2d_hal_interface Interface | ||
| 86 | + @} | ||
| 87 | + @} | ||
| 88 | + */ | ||
| 89 | + | ||
| 90 | +namespace cv | ||
| 91 | +{ | ||
| 92 | + | ||
| 93 | +//! @addtogroup features2d | ||
| 94 | +//! @{ | ||
| 95 | + | ||
| 96 | +// //! writes vector of keypoints to the file storage | ||
| 97 | +// CV_EXPORTS void write(FileStorage& fs, const String& name, const std::vector<KeyPoint>& keypoints); | ||
| 98 | +// //! reads vector of keypoints from the specified file storage node | ||
| 99 | +// CV_EXPORTS void read(const FileNode& node, CV_OUT std::vector<KeyPoint>& keypoints); | ||
| 100 | + | ||
| 101 | +/** @brief A class filters a vector of keypoints. | ||
| 102 | + | ||
| 103 | + Because now it is difficult to provide a convenient interface for all usage scenarios of the | ||
| 104 | + keypoints filter class, it has only several needed by now static methods. | ||
| 105 | + */ | ||
| 106 | +class CV_EXPORTS KeyPointsFilter | ||
| 107 | +{ | ||
| 108 | +public: | ||
| 109 | + KeyPointsFilter(){} | ||
| 110 | + | ||
| 111 | + /* | ||
| 112 | + * Remove keypoints within borderPixels of an image edge. | ||
| 113 | + */ | ||
| 114 | + static void runByImageBorder( std::vector<KeyPoint>& keypoints, Size imageSize, int borderSize ); | ||
| 115 | + /* | ||
| 116 | + * Remove keypoints of sizes out of range. | ||
| 117 | + */ | ||
| 118 | + static void runByKeypointSize( std::vector<KeyPoint>& keypoints, float minSize, | ||
| 119 | + float maxSize=FLT_MAX ); | ||
| 120 | + /* | ||
| 121 | + * Remove keypoints from some image by mask for pixels of this image. | ||
| 122 | + */ | ||
| 123 | + static void runByPixelsMask( std::vector<KeyPoint>& keypoints, const Mat& mask ); | ||
| 124 | + /* | ||
| 125 | + * Remove duplicated keypoints. | ||
| 126 | + */ | ||
| 127 | + static void removeDuplicated( std::vector<KeyPoint>& keypoints ); | ||
| 128 | + /* | ||
| 129 | + * Remove duplicated keypoints and sort the remaining keypoints | ||
| 130 | + */ | ||
| 131 | + static void removeDuplicatedSorted( std::vector<KeyPoint>& keypoints ); | ||
| 132 | + | ||
| 133 | + /* | ||
| 134 | + * Retain the specified number of the best keypoints (according to the response) | ||
| 135 | + */ | ||
| 136 | + static void retainBest( std::vector<KeyPoint>& keypoints, int npoints ); | ||
| 137 | +}; | ||
| 138 | + | ||
| 139 | + | ||
| 140 | +/************************************ Base Classes ************************************/ | ||
| 141 | + | ||
| 142 | +/** @brief Abstract base class for 2D image feature detectors and descriptor extractors | ||
| 143 | +*/ | ||
| 144 | +#ifdef __EMSCRIPTEN__ | ||
| 145 | +class CV_EXPORTS_W Feature2D : public Algorithm | ||
| 146 | +#else | ||
| 147 | +class CV_EXPORTS_W Feature2D : public virtual Algorithm | ||
| 148 | +#endif | ||
| 149 | +{ | ||
| 150 | +public: | ||
| 151 | + virtual ~Feature2D(); | ||
| 152 | + | ||
| 153 | + /** @brief Detects keypoints in an image (first variant) or image set (second variant). | ||
| 154 | + | ||
| 155 | + @param image Image. | ||
| 156 | + @param keypoints The detected keypoints. In the second variant of the method keypoints[i] is a set | ||
| 157 | + of keypoints detected in images[i] . | ||
| 158 | + @param mask Mask specifying where to look for keypoints (optional). It must be a 8-bit integer | ||
| 159 | + matrix with non-zero values in the region of interest. | ||
| 160 | + */ | ||
| 161 | + CV_WRAP virtual void detect( InputArray image, | ||
| 162 | + CV_OUT std::vector<KeyPoint>& keypoints, | ||
| 163 | + InputArray mask=noArray() ); | ||
| 164 | + | ||
| 165 | + /** @overload | ||
| 166 | + @param images Image set. | ||
| 167 | + @param keypoints The detected keypoints. In the second variant of the method keypoints[i] is a set | ||
| 168 | + of keypoints detected in images[i] . | ||
| 169 | + @param masks Masks for each input image specifying where to look for keypoints (optional). | ||
| 170 | + masks[i] is a mask for images[i]. | ||
| 171 | + */ | ||
| 172 | + CV_WRAP virtual void detect( InputArrayOfArrays images, | ||
| 173 | + CV_OUT std::vector<std::vector<KeyPoint> >& keypoints, | ||
| 174 | + InputArrayOfArrays masks=noArray() ); | ||
| 175 | + | ||
| 176 | + /** @brief Computes the descriptors for a set of keypoints detected in an image (first variant) or image set | ||
| 177 | + (second variant). | ||
| 178 | + | ||
| 179 | + @param image Image. | ||
| 180 | + @param keypoints Input collection of keypoints. Keypoints for which a descriptor cannot be | ||
| 181 | + computed are removed. Sometimes new keypoints can be added, for example: SIFT duplicates keypoint | ||
| 182 | + with several dominant orientations (for each orientation). | ||
| 183 | + @param descriptors Computed descriptors. In the second variant of the method descriptors[i] are | ||
| 184 | + descriptors computed for a keypoints[i]. Row j is the keypoints (or keypoints[i]) is the | ||
| 185 | + descriptor for keypoint j-th keypoint. | ||
| 186 | + */ | ||
| 187 | + CV_WRAP virtual void compute( InputArray image, | ||
| 188 | + CV_OUT CV_IN_OUT std::vector<KeyPoint>& keypoints, | ||
| 189 | + OutputArray descriptors ); | ||
| 190 | + | ||
| 191 | + /** @overload | ||
| 192 | + | ||
| 193 | + @param images Image set. | ||
| 194 | + @param keypoints Input collection of keypoints. Keypoints for which a descriptor cannot be | ||
| 195 | + computed are removed. Sometimes new keypoints can be added, for example: SIFT duplicates keypoint | ||
| 196 | + with several dominant orientations (for each orientation). | ||
| 197 | + @param descriptors Computed descriptors. In the second variant of the method descriptors[i] are | ||
| 198 | + descriptors computed for a keypoints[i]. Row j is the keypoints (or keypoints[i]) is the | ||
| 199 | + descriptor for keypoint j-th keypoint. | ||
| 200 | + */ | ||
| 201 | + CV_WRAP virtual void compute( InputArrayOfArrays images, | ||
| 202 | + CV_OUT CV_IN_OUT std::vector<std::vector<KeyPoint> >& keypoints, | ||
| 203 | + OutputArrayOfArrays descriptors ); | ||
| 204 | + | ||
| 205 | + /** Detects keypoints and computes the descriptors */ | ||
| 206 | + CV_WRAP virtual void detectAndCompute( InputArray image, InputArray mask, | ||
| 207 | + CV_OUT std::vector<KeyPoint>& keypoints, | ||
| 208 | + OutputArray descriptors, | ||
| 209 | + bool useProvidedKeypoints=false ); | ||
| 210 | + | ||
| 211 | + CV_WRAP virtual int descriptorSize() const; | ||
| 212 | + CV_WRAP virtual int descriptorType() const; | ||
| 213 | + CV_WRAP virtual int defaultNorm() const; | ||
| 214 | + | ||
| 215 | + CV_WRAP void write( const String& fileName ) const; | ||
| 216 | + | ||
| 217 | + CV_WRAP void read( const String& fileName ); | ||
| 218 | + | ||
| 219 | + virtual void write( FileStorage&) const CV_OVERRIDE; | ||
| 220 | + | ||
| 221 | + // see corresponding cv::Algorithm method | ||
| 222 | + CV_WRAP virtual void read( const FileNode&) CV_OVERRIDE; | ||
| 223 | + | ||
| 224 | + //! Return true if detector object is empty | ||
| 225 | + CV_WRAP virtual bool empty() const CV_OVERRIDE; | ||
| 226 | + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; | ||
| 227 | + | ||
| 228 | + // see corresponding cv::Algorithm method | ||
| 229 | + CV_WRAP inline void write(const Ptr<FileStorage>& fs, const String& name = String()) const { Algorithm::write(fs, name); } | ||
| 230 | +}; | ||
| 231 | + | ||
| 232 | +/** Feature detectors in OpenCV have wrappers with a common interface that enables you to easily switch | ||
| 233 | +between different algorithms solving the same problem. All objects that implement keypoint detectors | ||
| 234 | +inherit the FeatureDetector interface. */ | ||
| 235 | +typedef Feature2D FeatureDetector; | ||
| 236 | + | ||
| 237 | +/** Extractors of keypoint descriptors in OpenCV have wrappers with a common interface that enables you | ||
| 238 | +to easily switch between different algorithms solving the same problem. This section is devoted to | ||
| 239 | +computing descriptors represented as vectors in a multidimensional space. All objects that implement | ||
| 240 | +the vector descriptor extractors inherit the DescriptorExtractor interface. | ||
| 241 | + */ | ||
| 242 | +typedef Feature2D DescriptorExtractor; | ||
| 243 | + | ||
| 244 | +//! @addtogroup features2d_main | ||
| 245 | +//! @{ | ||
| 246 | + | ||
| 247 | + | ||
| 248 | +/** @brief Class for implementing the wrapper which makes detectors and extractors to be affine invariant, | ||
| 249 | +described as ASIFT in @cite YM11 . | ||
| 250 | +*/ | ||
| 251 | +class CV_EXPORTS_W AffineFeature : public Feature2D | ||
| 252 | +{ | ||
| 253 | +public: | ||
| 254 | + /** | ||
| 255 | + @param backend The detector/extractor you want to use as backend. | ||
| 256 | + @param maxTilt The highest power index of tilt factor. 5 is used in the paper as tilt sampling range n. | ||
| 257 | + @param minTilt The lowest power index of tilt factor. 0 is used in the paper. | ||
| 258 | + @param tiltStep Tilt sampling step \f$\delta_t\f$ in Algorithm 1 in the paper. | ||
| 259 | + @param rotateStepBase Rotation sampling step factor b in Algorithm 1 in the paper. | ||
| 260 | + */ | ||
| 261 | + CV_WRAP static Ptr<AffineFeature> create(const Ptr<Feature2D>& backend, | ||
| 262 | + int maxTilt = 5, int minTilt = 0, float tiltStep = 1.4142135623730951f, float rotateStepBase = 72); | ||
| 263 | + | ||
| 264 | + CV_WRAP virtual void setViewParams(const std::vector<float>& tilts, const std::vector<float>& rolls) = 0; | ||
| 265 | + CV_WRAP virtual void getViewParams(std::vector<float>& tilts, std::vector<float>& rolls) const = 0; | ||
| 266 | + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; | ||
| 267 | +}; | ||
| 268 | + | ||
| 269 | +typedef AffineFeature AffineFeatureDetector; | ||
| 270 | +typedef AffineFeature AffineDescriptorExtractor; | ||
| 271 | + | ||
| 272 | + | ||
| 273 | +/** @brief Class for extracting keypoints and computing descriptors using the Scale Invariant Feature Transform | ||
| 274 | +(SIFT) algorithm by D. Lowe @cite Lowe04 . | ||
| 275 | +*/ | ||
| 276 | +class CV_EXPORTS_W SIFT : public Feature2D | ||
| 277 | +{ | ||
| 278 | +public: | ||
| 279 | + /** | ||
| 280 | + @param nfeatures The number of best features to retain. The features are ranked by their scores | ||
| 281 | + (measured in SIFT algorithm as the local contrast) | ||
| 282 | + | ||
| 283 | + @param nOctaveLayers The number of layers in each octave. 3 is the value used in D. Lowe paper. The | ||
| 284 | + number of octaves is computed automatically from the image resolution. | ||
| 285 | + | ||
| 286 | + @param contrastThreshold The contrast threshold used to filter out weak features in semi-uniform | ||
| 287 | + (low-contrast) regions. The larger the threshold, the less features are produced by the detector. | ||
| 288 | + | ||
| 289 | + @note The contrast threshold will be divided by nOctaveLayers when the filtering is applied. When | ||
| 290 | + nOctaveLayers is set to default and if you want to use the value used in D. Lowe paper, 0.03, set | ||
| 291 | + this argument to 0.09. | ||
| 292 | + | ||
| 293 | + @param edgeThreshold The threshold used to filter out edge-like features. Note that the its meaning | ||
| 294 | + is different from the contrastThreshold, i.e. the larger the edgeThreshold, the less features are | ||
| 295 | + filtered out (more features are retained). | ||
| 296 | + | ||
| 297 | + @param sigma The sigma of the Gaussian applied to the input image at the octave \#0. If your image | ||
| 298 | + is captured with a weak camera with soft lenses, you might want to reduce the number. | ||
| 299 | + */ | ||
| 300 | + CV_WRAP static Ptr<SIFT> create(int nfeatures = 0, int nOctaveLayers = 3, | ||
| 301 | + double contrastThreshold = 0.04, double edgeThreshold = 10, | ||
| 302 | + double sigma = 1.6); | ||
| 303 | + | ||
| 304 | + /** @brief Create SIFT with specified descriptorType. | ||
| 305 | + @param nfeatures The number of best features to retain. The features are ranked by their scores | ||
| 306 | + (measured in SIFT algorithm as the local contrast) | ||
| 307 | + | ||
| 308 | + @param nOctaveLayers The number of layers in each octave. 3 is the value used in D. Lowe paper. The | ||
| 309 | + number of octaves is computed automatically from the image resolution. | ||
| 310 | + | ||
| 311 | + @param contrastThreshold The contrast threshold used to filter out weak features in semi-uniform | ||
| 312 | + (low-contrast) regions. The larger the threshold, the less features are produced by the detector. | ||
| 313 | + | ||
| 314 | + @note The contrast threshold will be divided by nOctaveLayers when the filtering is applied. When | ||
| 315 | + nOctaveLayers is set to default and if you want to use the value used in D. Lowe paper, 0.03, set | ||
| 316 | + this argument to 0.09. | ||
| 317 | + | ||
| 318 | + @param edgeThreshold The threshold used to filter out edge-like features. Note that the its meaning | ||
| 319 | + is different from the contrastThreshold, i.e. the larger the edgeThreshold, the less features are | ||
| 320 | + filtered out (more features are retained). | ||
| 321 | + | ||
| 322 | + @param sigma The sigma of the Gaussian applied to the input image at the octave \#0. If your image | ||
| 323 | + is captured with a weak camera with soft lenses, you might want to reduce the number. | ||
| 324 | + | ||
| 325 | + @param descriptorType The type of descriptors. Only CV_32F and CV_8U are supported. | ||
| 326 | + */ | ||
| 327 | + CV_WRAP static Ptr<SIFT> create(int nfeatures, int nOctaveLayers, | ||
| 328 | + double contrastThreshold, double edgeThreshold, | ||
| 329 | + double sigma, int descriptorType); | ||
| 330 | + | ||
| 331 | + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; | ||
| 332 | +}; | ||
| 333 | + | ||
| 334 | +typedef SIFT SiftFeatureDetector; | ||
| 335 | +typedef SIFT SiftDescriptorExtractor; | ||
| 336 | + | ||
| 337 | + | ||
| 338 | +/** @brief Class implementing the BRISK keypoint detector and descriptor extractor, described in @cite LCS11 . | ||
| 339 | + */ | ||
| 340 | +class CV_EXPORTS_W BRISK : public Feature2D | ||
| 341 | +{ | ||
| 342 | +public: | ||
| 343 | + /** @brief The BRISK constructor | ||
| 344 | + | ||
| 345 | + @param thresh AGAST detection threshold score. | ||
| 346 | + @param octaves detection octaves. Use 0 to do single scale. | ||
| 347 | + @param patternScale apply this scale to the pattern used for sampling the neighbourhood of a | ||
| 348 | + keypoint. | ||
| 349 | + */ | ||
| 350 | + CV_WRAP static Ptr<BRISK> create(int thresh=30, int octaves=3, float patternScale=1.0f); | ||
| 351 | + | ||
| 352 | + /** @brief The BRISK constructor for a custom pattern | ||
| 353 | + | ||
| 354 | + @param radiusList defines the radii (in pixels) where the samples around a keypoint are taken (for | ||
| 355 | + keypoint scale 1). | ||
| 356 | + @param numberList defines the number of sampling points on the sampling circle. Must be the same | ||
| 357 | + size as radiusList.. | ||
| 358 | + @param dMax threshold for the short pairings used for descriptor formation (in pixels for keypoint | ||
| 359 | + scale 1). | ||
| 360 | + @param dMin threshold for the long pairings used for orientation determination (in pixels for | ||
| 361 | + keypoint scale 1). | ||
| 362 | + @param indexChange index remapping of the bits. */ | ||
| 363 | + CV_WRAP static Ptr<BRISK> create(const std::vector<float> &radiusList, const std::vector<int> &numberList, | ||
| 364 | + float dMax=5.85f, float dMin=8.2f, const std::vector<int>& indexChange=std::vector<int>()); | ||
| 365 | + | ||
| 366 | + /** @brief The BRISK constructor for a custom pattern, detection threshold and octaves | ||
| 367 | + | ||
| 368 | + @param thresh AGAST detection threshold score. | ||
| 369 | + @param octaves detection octaves. Use 0 to do single scale. | ||
| 370 | + @param radiusList defines the radii (in pixels) where the samples around a keypoint are taken (for | ||
| 371 | + keypoint scale 1). | ||
| 372 | + @param numberList defines the number of sampling points on the sampling circle. Must be the same | ||
| 373 | + size as radiusList.. | ||
| 374 | + @param dMax threshold for the short pairings used for descriptor formation (in pixels for keypoint | ||
| 375 | + scale 1). | ||
| 376 | + @param dMin threshold for the long pairings used for orientation determination (in pixels for | ||
| 377 | + keypoint scale 1). | ||
| 378 | + @param indexChange index remapping of the bits. */ | ||
| 379 | + CV_WRAP static Ptr<BRISK> create(int thresh, int octaves, const std::vector<float> &radiusList, | ||
| 380 | + const std::vector<int> &numberList, float dMax=5.85f, float dMin=8.2f, | ||
| 381 | + const std::vector<int>& indexChange=std::vector<int>()); | ||
| 382 | + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; | ||
| 383 | + | ||
| 384 | + /** @brief Set detection threshold. | ||
| 385 | + @param threshold AGAST detection threshold score. | ||
| 386 | + */ | ||
| 387 | + CV_WRAP virtual void setThreshold(int threshold) { CV_UNUSED(threshold); return; } | ||
| 388 | + CV_WRAP virtual int getThreshold() const { return -1; } | ||
| 389 | + | ||
| 390 | + /** @brief Set detection octaves. | ||
| 391 | + @param octaves detection octaves. Use 0 to do single scale. | ||
| 392 | + */ | ||
| 393 | + CV_WRAP virtual void setOctaves(int octaves) { CV_UNUSED(octaves); return; } | ||
| 394 | + CV_WRAP virtual int getOctaves() const { return -1; } | ||
| 395 | +}; | ||
| 396 | + | ||
| 397 | +/** @brief Class implementing the ORB (*oriented BRIEF*) keypoint detector and descriptor extractor | ||
| 398 | + | ||
| 399 | +described in @cite RRKB11 . The algorithm uses FAST in pyramids to detect stable keypoints, selects | ||
| 400 | +the strongest features using FAST or Harris response, finds their orientation using first-order | ||
| 401 | +moments and computes the descriptors using BRIEF (where the coordinates of random point pairs (or | ||
| 402 | +k-tuples) are rotated according to the measured orientation). | ||
| 403 | + */ | ||
| 404 | +class CV_EXPORTS_W ORB : public Feature2D | ||
| 405 | +{ | ||
| 406 | +public: | ||
| 407 | + enum ScoreType { HARRIS_SCORE=0, FAST_SCORE=1 }; | ||
| 408 | + static const int kBytes = 32; | ||
| 409 | + | ||
| 410 | + /** @brief The ORB constructor | ||
| 411 | + | ||
| 412 | + @param nfeatures The maximum number of features to retain. | ||
| 413 | + @param scaleFactor Pyramid decimation ratio, greater than 1. scaleFactor==2 means the classical | ||
| 414 | + pyramid, where each next level has 4x less pixels than the previous, but such a big scale factor | ||
| 415 | + will degrade feature matching scores dramatically. On the other hand, too close to 1 scale factor | ||
| 416 | + will mean that to cover certain scale range you will need more pyramid levels and so the speed | ||
| 417 | + will suffer. | ||
| 418 | + @param nlevels The number of pyramid levels. The smallest level will have linear size equal to | ||
| 419 | + input_image_linear_size/pow(scaleFactor, nlevels - firstLevel). | ||
| 420 | + @param edgeThreshold This is size of the border where the features are not detected. It should | ||
| 421 | + roughly match the patchSize parameter. | ||
| 422 | + @param firstLevel The level of pyramid to put source image to. Previous layers are filled | ||
| 423 | + with upscaled source image. | ||
| 424 | + @param WTA_K The number of points that produce each element of the oriented BRIEF descriptor. The | ||
| 425 | + default value 2 means the BRIEF where we take a random point pair and compare their brightnesses, | ||
| 426 | + so we get 0/1 response. Other possible values are 3 and 4. For example, 3 means that we take 3 | ||
| 427 | + random points (of course, those point coordinates are random, but they are generated from the | ||
| 428 | + pre-defined seed, so each element of BRIEF descriptor is computed deterministically from the pixel | ||
| 429 | + rectangle), find point of maximum brightness and output index of the winner (0, 1 or 2). Such | ||
| 430 | + output will occupy 2 bits, and therefore it will need a special variant of Hamming distance, | ||
| 431 | + denoted as NORM_HAMMING2 (2 bits per bin). When WTA_K=4, we take 4 random points to compute each | ||
| 432 | + bin (that will also occupy 2 bits with possible values 0, 1, 2 or 3). | ||
| 433 | + @param scoreType The default HARRIS_SCORE means that Harris algorithm is used to rank features | ||
| 434 | + (the score is written to KeyPoint::score and is used to retain best nfeatures features); | ||
| 435 | + FAST_SCORE is alternative value of the parameter that produces slightly less stable keypoints, | ||
| 436 | + but it is a little faster to compute. | ||
| 437 | + @param patchSize size of the patch used by the oriented BRIEF descriptor. Of course, on smaller | ||
| 438 | + pyramid layers the perceived image area covered by a feature will be larger. | ||
| 439 | + @param fastThreshold the fast threshold | ||
| 440 | + */ | ||
| 441 | + CV_WRAP static Ptr<ORB> create(int nfeatures=500, float scaleFactor=1.2f, int nlevels=8, int edgeThreshold=31, | ||
| 442 | + int firstLevel=0, int WTA_K=2, ORB::ScoreType scoreType=ORB::HARRIS_SCORE, int patchSize=31, int fastThreshold=20); | ||
| 443 | + | ||
| 444 | + CV_WRAP virtual void setMaxFeatures(int maxFeatures) = 0; | ||
| 445 | + CV_WRAP virtual int getMaxFeatures() const = 0; | ||
| 446 | + | ||
| 447 | + CV_WRAP virtual void setScaleFactor(double scaleFactor) = 0; | ||
| 448 | + CV_WRAP virtual double getScaleFactor() const = 0; | ||
| 449 | + | ||
| 450 | + CV_WRAP virtual void setNLevels(int nlevels) = 0; | ||
| 451 | + CV_WRAP virtual int getNLevels() const = 0; | ||
| 452 | + | ||
| 453 | + CV_WRAP virtual void setEdgeThreshold(int edgeThreshold) = 0; | ||
| 454 | + CV_WRAP virtual int getEdgeThreshold() const = 0; | ||
| 455 | + | ||
| 456 | + CV_WRAP virtual void setFirstLevel(int firstLevel) = 0; | ||
| 457 | + CV_WRAP virtual int getFirstLevel() const = 0; | ||
| 458 | + | ||
| 459 | + CV_WRAP virtual void setWTA_K(int wta_k) = 0; | ||
| 460 | + CV_WRAP virtual int getWTA_K() const = 0; | ||
| 461 | + | ||
| 462 | + CV_WRAP virtual void setScoreType(ORB::ScoreType scoreType) = 0; | ||
| 463 | + CV_WRAP virtual ORB::ScoreType getScoreType() const = 0; | ||
| 464 | + | ||
| 465 | + CV_WRAP virtual void setPatchSize(int patchSize) = 0; | ||
| 466 | + CV_WRAP virtual int getPatchSize() const = 0; | ||
| 467 | + | ||
| 468 | + CV_WRAP virtual void setFastThreshold(int fastThreshold) = 0; | ||
| 469 | + CV_WRAP virtual int getFastThreshold() const = 0; | ||
| 470 | + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; | ||
| 471 | +}; | ||
| 472 | + | ||
| 473 | +/** @brief Maximally stable extremal region extractor | ||
| 474 | + | ||
| 475 | +The class encapsulates all the parameters of the %MSER extraction algorithm (see [wiki | ||
| 476 | +article](http://en.wikipedia.org/wiki/Maximally_stable_extremal_regions)). | ||
| 477 | + | ||
| 478 | +- there are two different implementation of %MSER: one for grey image, one for color image | ||
| 479 | + | ||
| 480 | +- the grey image algorithm is taken from: @cite nister2008linear ; the paper claims to be faster | ||
| 481 | +than union-find method; it actually get 1.5~2m/s on my centrino L7200 1.2GHz laptop. | ||
| 482 | + | ||
| 483 | +- the color image algorithm is taken from: @cite forssen2007maximally ; it should be much slower | ||
| 484 | +than grey image method ( 3~4 times ) | ||
| 485 | + | ||
| 486 | +- (Python) A complete example showing the use of the %MSER detector can be found at samples/python/mser.py | ||
| 487 | +*/ | ||
| 488 | +class CV_EXPORTS_W MSER : public Feature2D | ||
| 489 | +{ | ||
| 490 | +public: | ||
| 491 | + /** @brief Full constructor for %MSER detector | ||
| 492 | + | ||
| 493 | + @param _delta it compares \f$(size_{i}-size_{i-delta})/size_{i-delta}\f$ | ||
| 494 | + @param _min_area prune the area which smaller than minArea | ||
| 495 | + @param _max_area prune the area which bigger than maxArea | ||
| 496 | + @param _max_variation prune the area have similar size to its children | ||
| 497 | + @param _min_diversity for color image, trace back to cut off mser with diversity less than min_diversity | ||
| 498 | + @param _max_evolution for color image, the evolution steps | ||
| 499 | + @param _area_threshold for color image, the area threshold to cause re-initialize | ||
| 500 | + @param _min_margin for color image, ignore too small margin | ||
| 501 | + @param _edge_blur_size for color image, the aperture size for edge blur | ||
| 502 | + */ | ||
| 503 | + CV_WRAP static Ptr<MSER> create( int _delta=5, int _min_area=60, int _max_area=14400, | ||
| 504 | + double _max_variation=0.25, double _min_diversity=.2, | ||
| 505 | + int _max_evolution=200, double _area_threshold=1.01, | ||
| 506 | + double _min_margin=0.003, int _edge_blur_size=5 ); | ||
| 507 | + | ||
| 508 | + /** @brief Detect %MSER regions | ||
| 509 | + | ||
| 510 | + @param image input image (8UC1, 8UC3 or 8UC4, must be greater or equal than 3x3) | ||
| 511 | + @param msers resulting list of point sets | ||
| 512 | + @param bboxes resulting bounding boxes | ||
| 513 | + */ | ||
| 514 | + CV_WRAP virtual void detectRegions( InputArray image, | ||
| 515 | + CV_OUT std::vector<std::vector<Point> >& msers, | ||
| 516 | + CV_OUT std::vector<Rect>& bboxes ) = 0; | ||
| 517 | + | ||
| 518 | + CV_WRAP virtual void setDelta(int delta) = 0; | ||
| 519 | + CV_WRAP virtual int getDelta() const = 0; | ||
| 520 | + | ||
| 521 | + CV_WRAP virtual void setMinArea(int minArea) = 0; | ||
| 522 | + CV_WRAP virtual int getMinArea() const = 0; | ||
| 523 | + | ||
| 524 | + CV_WRAP virtual void setMaxArea(int maxArea) = 0; | ||
| 525 | + CV_WRAP virtual int getMaxArea() const = 0; | ||
| 526 | + | ||
| 527 | + CV_WRAP virtual void setPass2Only(bool f) = 0; | ||
| 528 | + CV_WRAP virtual bool getPass2Only() const = 0; | ||
| 529 | + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; | ||
| 530 | +}; | ||
| 531 | + | ||
| 532 | +//! @} features2d_main | ||
| 533 | + | ||
| 534 | +//! @addtogroup features2d_main | ||
| 535 | +//! @{ | ||
| 536 | + | ||
| 537 | +/** @brief Wrapping class for feature detection using the FAST method. : | ||
| 538 | + */ | ||
| 539 | +class CV_EXPORTS_W FastFeatureDetector : public Feature2D | ||
| 540 | +{ | ||
| 541 | +public: | ||
| 542 | + enum DetectorType | ||
| 543 | + { | ||
| 544 | + TYPE_5_8 = 0, TYPE_7_12 = 1, TYPE_9_16 = 2 | ||
| 545 | + }; | ||
| 546 | + enum | ||
| 547 | + { | ||
| 548 | + THRESHOLD = 10000, NONMAX_SUPPRESSION=10001, FAST_N=10002 | ||
| 549 | + }; | ||
| 550 | + | ||
| 551 | + | ||
| 552 | + CV_WRAP static Ptr<FastFeatureDetector> create( int threshold=10, | ||
| 553 | + bool nonmaxSuppression=true, | ||
| 554 | + FastFeatureDetector::DetectorType type=FastFeatureDetector::TYPE_9_16 ); | ||
| 555 | + | ||
| 556 | + CV_WRAP virtual void setThreshold(int threshold) = 0; | ||
| 557 | + CV_WRAP virtual int getThreshold() const = 0; | ||
| 558 | + | ||
| 559 | + CV_WRAP virtual void setNonmaxSuppression(bool f) = 0; | ||
| 560 | + CV_WRAP virtual bool getNonmaxSuppression() const = 0; | ||
| 561 | + | ||
| 562 | + CV_WRAP virtual void setType(FastFeatureDetector::DetectorType type) = 0; | ||
| 563 | + CV_WRAP virtual FastFeatureDetector::DetectorType getType() const = 0; | ||
| 564 | + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; | ||
| 565 | +}; | ||
| 566 | + | ||
| 567 | +/** @overload */ | ||
| 568 | +CV_EXPORTS void FAST( InputArray image, CV_OUT std::vector<KeyPoint>& keypoints, | ||
| 569 | + int threshold, bool nonmaxSuppression=true ); | ||
| 570 | + | ||
| 571 | +/** @brief Detects corners using the FAST algorithm | ||
| 572 | + | ||
| 573 | +@param image grayscale image where keypoints (corners) are detected. | ||
| 574 | +@param keypoints keypoints detected on the image. | ||
| 575 | +@param threshold threshold on difference between intensity of the central pixel and pixels of a | ||
| 576 | +circle around this pixel. | ||
| 577 | +@param nonmaxSuppression if true, non-maximum suppression is applied to detected corners | ||
| 578 | +(keypoints). | ||
| 579 | +@param type one of the three neighborhoods as defined in the paper: | ||
| 580 | +FastFeatureDetector::TYPE_9_16, FastFeatureDetector::TYPE_7_12, | ||
| 581 | +FastFeatureDetector::TYPE_5_8 | ||
| 582 | + | ||
| 583 | +Detects corners using the FAST algorithm by @cite Rosten06 . | ||
| 584 | + | ||
| 585 | +@note In Python API, types are given as cv.FAST_FEATURE_DETECTOR_TYPE_5_8, | ||
| 586 | +cv.FAST_FEATURE_DETECTOR_TYPE_7_12 and cv.FAST_FEATURE_DETECTOR_TYPE_9_16. For corner | ||
| 587 | +detection, use cv.FAST.detect() method. | ||
| 588 | + */ | ||
| 589 | +CV_EXPORTS void FAST( InputArray image, CV_OUT std::vector<KeyPoint>& keypoints, | ||
| 590 | + int threshold, bool nonmaxSuppression, FastFeatureDetector::DetectorType type ); | ||
| 591 | + | ||
| 592 | +//! @} features2d_main | ||
| 593 | + | ||
| 594 | +//! @addtogroup features2d_main | ||
| 595 | +//! @{ | ||
| 596 | + | ||
| 597 | +/** @brief Wrapping class for feature detection using the AGAST method. : | ||
| 598 | + */ | ||
| 599 | +class CV_EXPORTS_W AgastFeatureDetector : public Feature2D | ||
| 600 | +{ | ||
| 601 | +public: | ||
| 602 | + enum DetectorType | ||
| 603 | + { | ||
| 604 | + AGAST_5_8 = 0, AGAST_7_12d = 1, AGAST_7_12s = 2, OAST_9_16 = 3, | ||
| 605 | + }; | ||
| 606 | + | ||
| 607 | + enum | ||
| 608 | + { | ||
| 609 | + THRESHOLD = 10000, NONMAX_SUPPRESSION = 10001, | ||
| 610 | + }; | ||
| 611 | + | ||
| 612 | + CV_WRAP static Ptr<AgastFeatureDetector> create( int threshold=10, | ||
| 613 | + bool nonmaxSuppression=true, | ||
| 614 | + AgastFeatureDetector::DetectorType type = AgastFeatureDetector::OAST_9_16); | ||
| 615 | + | ||
| 616 | + CV_WRAP virtual void setThreshold(int threshold) = 0; | ||
| 617 | + CV_WRAP virtual int getThreshold() const = 0; | ||
| 618 | + | ||
| 619 | + CV_WRAP virtual void setNonmaxSuppression(bool f) = 0; | ||
| 620 | + CV_WRAP virtual bool getNonmaxSuppression() const = 0; | ||
| 621 | + | ||
| 622 | + CV_WRAP virtual void setType(AgastFeatureDetector::DetectorType type) = 0; | ||
| 623 | + CV_WRAP virtual AgastFeatureDetector::DetectorType getType() const = 0; | ||
| 624 | + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; | ||
| 625 | +}; | ||
| 626 | + | ||
| 627 | +/** @overload */ | ||
| 628 | +CV_EXPORTS void AGAST( InputArray image, CV_OUT std::vector<KeyPoint>& keypoints, | ||
| 629 | + int threshold, bool nonmaxSuppression=true ); | ||
| 630 | + | ||
| 631 | +/** @brief Detects corners using the AGAST algorithm | ||
| 632 | + | ||
| 633 | +@param image grayscale image where keypoints (corners) are detected. | ||
| 634 | +@param keypoints keypoints detected on the image. | ||
| 635 | +@param threshold threshold on difference between intensity of the central pixel and pixels of a | ||
| 636 | +circle around this pixel. | ||
| 637 | +@param nonmaxSuppression if true, non-maximum suppression is applied to detected corners | ||
| 638 | +(keypoints). | ||
| 639 | +@param type one of the four neighborhoods as defined in the paper: | ||
| 640 | +AgastFeatureDetector::AGAST_5_8, AgastFeatureDetector::AGAST_7_12d, | ||
| 641 | +AgastFeatureDetector::AGAST_7_12s, AgastFeatureDetector::OAST_9_16 | ||
| 642 | + | ||
| 643 | +For non-Intel platforms, there is a tree optimised variant of AGAST with same numerical results. | ||
| 644 | +The 32-bit binary tree tables were generated automatically from original code using perl script. | ||
| 645 | +The perl script and examples of tree generation are placed in features2d/doc folder. | ||
| 646 | +Detects corners using the AGAST algorithm by @cite mair2010_agast . | ||
| 647 | + | ||
| 648 | + */ | ||
| 649 | +CV_EXPORTS void AGAST( InputArray image, CV_OUT std::vector<KeyPoint>& keypoints, | ||
| 650 | + int threshold, bool nonmaxSuppression, AgastFeatureDetector::DetectorType type ); | ||
| 651 | + | ||
| 652 | +/** @brief Wrapping class for feature detection using the goodFeaturesToTrack function. : | ||
| 653 | + */ | ||
| 654 | +class CV_EXPORTS_W GFTTDetector : public Feature2D | ||
| 655 | +{ | ||
| 656 | +public: | ||
| 657 | + CV_WRAP static Ptr<GFTTDetector> create( int maxCorners=1000, double qualityLevel=0.01, double minDistance=1, | ||
| 658 | + int blockSize=3, bool useHarrisDetector=false, double k=0.04 ); | ||
| 659 | + CV_WRAP static Ptr<GFTTDetector> create( int maxCorners, double qualityLevel, double minDistance, | ||
| 660 | + int blockSize, int gradiantSize, bool useHarrisDetector=false, double k=0.04 ); | ||
| 661 | + CV_WRAP virtual void setMaxFeatures(int maxFeatures) = 0; | ||
| 662 | + CV_WRAP virtual int getMaxFeatures() const = 0; | ||
| 663 | + | ||
| 664 | + CV_WRAP virtual void setQualityLevel(double qlevel) = 0; | ||
| 665 | + CV_WRAP virtual double getQualityLevel() const = 0; | ||
| 666 | + | ||
| 667 | + CV_WRAP virtual void setMinDistance(double minDistance) = 0; | ||
| 668 | + CV_WRAP virtual double getMinDistance() const = 0; | ||
| 669 | + | ||
| 670 | + CV_WRAP virtual void setBlockSize(int blockSize) = 0; | ||
| 671 | + CV_WRAP virtual int getBlockSize() const = 0; | ||
| 672 | + | ||
| 673 | + CV_WRAP virtual void setHarrisDetector(bool val) = 0; | ||
| 674 | + CV_WRAP virtual bool getHarrisDetector() const = 0; | ||
| 675 | + | ||
| 676 | + CV_WRAP virtual void setK(double k) = 0; | ||
| 677 | + CV_WRAP virtual double getK() const = 0; | ||
| 678 | + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; | ||
| 679 | +}; | ||
| 680 | + | ||
| 681 | +/** @brief Class for extracting blobs from an image. : | ||
| 682 | + | ||
| 683 | +The class implements a simple algorithm for extracting blobs from an image: | ||
| 684 | + | ||
| 685 | +1. Convert the source image to binary images by applying thresholding with several thresholds from | ||
| 686 | + minThreshold (inclusive) to maxThreshold (exclusive) with distance thresholdStep between | ||
| 687 | + neighboring thresholds. | ||
| 688 | +2. Extract connected components from every binary image by findContours and calculate their | ||
| 689 | + centers. | ||
| 690 | +3. Group centers from several binary images by their coordinates. Close centers form one group that | ||
| 691 | + corresponds to one blob, which is controlled by the minDistBetweenBlobs parameter. | ||
| 692 | +4. From the groups, estimate final centers of blobs and their radiuses and return as locations and | ||
| 693 | + sizes of keypoints. | ||
| 694 | + | ||
| 695 | +This class performs several filtrations of returned blobs. You should set filterBy\* to true/false | ||
| 696 | +to turn on/off corresponding filtration. Available filtrations: | ||
| 697 | + | ||
| 698 | +- **By color**. This filter compares the intensity of a binary image at the center of a blob to | ||
| 699 | +blobColor. If they differ, the blob is filtered out. Use blobColor = 0 to extract dark blobs | ||
| 700 | +and blobColor = 255 to extract light blobs. | ||
| 701 | +- **By area**. Extracted blobs have an area between minArea (inclusive) and maxArea (exclusive). | ||
| 702 | +- **By circularity**. Extracted blobs have circularity | ||
| 703 | +(\f$\frac{4*\pi*Area}{perimeter * perimeter}\f$) between minCircularity (inclusive) and | ||
| 704 | +maxCircularity (exclusive). | ||
| 705 | +- **By ratio of the minimum inertia to maximum inertia**. Extracted blobs have this ratio | ||
| 706 | +between minInertiaRatio (inclusive) and maxInertiaRatio (exclusive). | ||
| 707 | +- **By convexity**. Extracted blobs have convexity (area / area of blob convex hull) between | ||
| 708 | +minConvexity (inclusive) and maxConvexity (exclusive). | ||
| 709 | + | ||
| 710 | +Default values of parameters are tuned to extract dark circular blobs. | ||
| 711 | + */ | ||
| 712 | +class CV_EXPORTS_W SimpleBlobDetector : public Feature2D | ||
| 713 | +{ | ||
| 714 | +public: | ||
| 715 | + struct CV_EXPORTS_W_SIMPLE Params | ||
| 716 | + { | ||
| 717 | + CV_WRAP Params(); | ||
| 718 | + CV_PROP_RW float thresholdStep; | ||
| 719 | + CV_PROP_RW float minThreshold; | ||
| 720 | + CV_PROP_RW float maxThreshold; | ||
| 721 | + CV_PROP_RW size_t minRepeatability; | ||
| 722 | + CV_PROP_RW float minDistBetweenBlobs; | ||
| 723 | + | ||
| 724 | + CV_PROP_RW bool filterByColor; | ||
| 725 | + CV_PROP_RW uchar blobColor; | ||
| 726 | + | ||
| 727 | + CV_PROP_RW bool filterByArea; | ||
| 728 | + CV_PROP_RW float minArea, maxArea; | ||
| 729 | + | ||
| 730 | + CV_PROP_RW bool filterByCircularity; | ||
| 731 | + CV_PROP_RW float minCircularity, maxCircularity; | ||
| 732 | + | ||
| 733 | + CV_PROP_RW bool filterByInertia; | ||
| 734 | + CV_PROP_RW float minInertiaRatio, maxInertiaRatio; | ||
| 735 | + | ||
| 736 | + CV_PROP_RW bool filterByConvexity; | ||
| 737 | + CV_PROP_RW float minConvexity, maxConvexity; | ||
| 738 | + | ||
| 739 | + void read( const FileNode& fn ); | ||
| 740 | + void write( FileStorage& fs ) const; | ||
| 741 | + }; | ||
| 742 | + | ||
| 743 | + CV_WRAP static Ptr<SimpleBlobDetector> | ||
| 744 | + create(const SimpleBlobDetector::Params ¶meters = SimpleBlobDetector::Params()); | ||
| 745 | + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; | ||
| 746 | +}; | ||
| 747 | + | ||
| 748 | +//! @} features2d_main | ||
| 749 | + | ||
| 750 | +//! @addtogroup features2d_main | ||
| 751 | +//! @{ | ||
| 752 | + | ||
| 753 | +/** @brief Class implementing the KAZE keypoint detector and descriptor extractor, described in @cite ABD12 . | ||
| 754 | + | ||
| 755 | +@note AKAZE descriptor can only be used with KAZE or AKAZE keypoints .. [ABD12] KAZE Features. Pablo | ||
| 756 | +F. Alcantarilla, Adrien Bartoli and Andrew J. Davison. In European Conference on Computer Vision | ||
| 757 | +(ECCV), Fiorenze, Italy, October 2012. | ||
| 758 | +*/ | ||
| 759 | +class CV_EXPORTS_W KAZE : public Feature2D | ||
| 760 | +{ | ||
| 761 | +public: | ||
| 762 | + enum DiffusivityType | ||
| 763 | + { | ||
| 764 | + DIFF_PM_G1 = 0, | ||
| 765 | + DIFF_PM_G2 = 1, | ||
| 766 | + DIFF_WEICKERT = 2, | ||
| 767 | + DIFF_CHARBONNIER = 3 | ||
| 768 | + }; | ||
| 769 | + | ||
| 770 | + /** @brief The KAZE constructor | ||
| 771 | + | ||
| 772 | + @param extended Set to enable extraction of extended (128-byte) descriptor. | ||
| 773 | + @param upright Set to enable use of upright descriptors (non rotation-invariant). | ||
| 774 | + @param threshold Detector response threshold to accept point | ||
| 775 | + @param nOctaves Maximum octave evolution of the image | ||
| 776 | + @param nOctaveLayers Default number of sublevels per scale level | ||
| 777 | + @param diffusivity Diffusivity type. DIFF_PM_G1, DIFF_PM_G2, DIFF_WEICKERT or | ||
| 778 | + DIFF_CHARBONNIER | ||
| 779 | + */ | ||
| 780 | + CV_WRAP static Ptr<KAZE> create(bool extended=false, bool upright=false, | ||
| 781 | + float threshold = 0.001f, | ||
| 782 | + int nOctaves = 4, int nOctaveLayers = 4, | ||
| 783 | + KAZE::DiffusivityType diffusivity = KAZE::DIFF_PM_G2); | ||
| 784 | + | ||
| 785 | + CV_WRAP virtual void setExtended(bool extended) = 0; | ||
| 786 | + CV_WRAP virtual bool getExtended() const = 0; | ||
| 787 | + | ||
| 788 | + CV_WRAP virtual void setUpright(bool upright) = 0; | ||
| 789 | + CV_WRAP virtual bool getUpright() const = 0; | ||
| 790 | + | ||
| 791 | + CV_WRAP virtual void setThreshold(double threshold) = 0; | ||
| 792 | + CV_WRAP virtual double getThreshold() const = 0; | ||
| 793 | + | ||
| 794 | + CV_WRAP virtual void setNOctaves(int octaves) = 0; | ||
| 795 | + CV_WRAP virtual int getNOctaves() const = 0; | ||
| 796 | + | ||
| 797 | + CV_WRAP virtual void setNOctaveLayers(int octaveLayers) = 0; | ||
| 798 | + CV_WRAP virtual int getNOctaveLayers() const = 0; | ||
| 799 | + | ||
| 800 | + CV_WRAP virtual void setDiffusivity(KAZE::DiffusivityType diff) = 0; | ||
| 801 | + CV_WRAP virtual KAZE::DiffusivityType getDiffusivity() const = 0; | ||
| 802 | + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; | ||
| 803 | +}; | ||
| 804 | + | ||
| 805 | +/** @brief Class implementing the AKAZE keypoint detector and descriptor extractor, described in @cite ANB13. | ||
| 806 | + | ||
| 807 | +@details AKAZE descriptors can only be used with KAZE or AKAZE keypoints. This class is thread-safe. | ||
| 808 | + | ||
| 809 | +@note When you need descriptors use Feature2D::detectAndCompute, which | ||
| 810 | +provides better performance. When using Feature2D::detect followed by | ||
| 811 | +Feature2D::compute scale space pyramid is computed twice. | ||
| 812 | + | ||
| 813 | +@note AKAZE implements T-API. When image is passed as UMat some parts of the algorithm | ||
| 814 | +will use OpenCL. | ||
| 815 | + | ||
| 816 | +@note [ANB13] Fast Explicit Diffusion for Accelerated Features in Nonlinear | ||
| 817 | +Scale Spaces. Pablo F. Alcantarilla, Jesús Nuevo and Adrien Bartoli. In | ||
| 818 | +British Machine Vision Conference (BMVC), Bristol, UK, September 2013. | ||
| 819 | + | ||
| 820 | +*/ | ||
| 821 | +class CV_EXPORTS_W AKAZE : public Feature2D | ||
| 822 | +{ | ||
| 823 | +public: | ||
| 824 | + // AKAZE descriptor type | ||
| 825 | + enum DescriptorType | ||
| 826 | + { | ||
| 827 | + DESCRIPTOR_KAZE_UPRIGHT = 2, ///< Upright descriptors, not invariant to rotation | ||
| 828 | + DESCRIPTOR_KAZE = 3, | ||
| 829 | + DESCRIPTOR_MLDB_UPRIGHT = 4, ///< Upright descriptors, not invariant to rotation | ||
| 830 | + DESCRIPTOR_MLDB = 5 | ||
| 831 | + }; | ||
| 832 | + | ||
| 833 | + /** @brief The AKAZE constructor | ||
| 834 | + | ||
| 835 | + @param descriptor_type Type of the extracted descriptor: DESCRIPTOR_KAZE, | ||
| 836 | + DESCRIPTOR_KAZE_UPRIGHT, DESCRIPTOR_MLDB or DESCRIPTOR_MLDB_UPRIGHT. | ||
| 837 | + @param descriptor_size Size of the descriptor in bits. 0 -\> Full size | ||
| 838 | + @param descriptor_channels Number of channels in the descriptor (1, 2, 3) | ||
| 839 | + @param threshold Detector response threshold to accept point | ||
| 840 | + @param nOctaves Maximum octave evolution of the image | ||
| 841 | + @param nOctaveLayers Default number of sublevels per scale level | ||
| 842 | + @param diffusivity Diffusivity type. DIFF_PM_G1, DIFF_PM_G2, DIFF_WEICKERT or | ||
| 843 | + DIFF_CHARBONNIER | ||
| 844 | + */ | ||
| 845 | + CV_WRAP static Ptr<AKAZE> create(AKAZE::DescriptorType descriptor_type = AKAZE::DESCRIPTOR_MLDB, | ||
| 846 | + int descriptor_size = 0, int descriptor_channels = 3, | ||
| 847 | + float threshold = 0.001f, int nOctaves = 4, | ||
| 848 | + int nOctaveLayers = 4, KAZE::DiffusivityType diffusivity = KAZE::DIFF_PM_G2); | ||
| 849 | + | ||
| 850 | + CV_WRAP virtual void setDescriptorType(AKAZE::DescriptorType dtype) = 0; | ||
| 851 | + CV_WRAP virtual AKAZE::DescriptorType getDescriptorType() const = 0; | ||
| 852 | + | ||
| 853 | + CV_WRAP virtual void setDescriptorSize(int dsize) = 0; | ||
| 854 | + CV_WRAP virtual int getDescriptorSize() const = 0; | ||
| 855 | + | ||
| 856 | + CV_WRAP virtual void setDescriptorChannels(int dch) = 0; | ||
| 857 | + CV_WRAP virtual int getDescriptorChannels() const = 0; | ||
| 858 | + | ||
| 859 | + CV_WRAP virtual void setThreshold(double threshold) = 0; | ||
| 860 | + CV_WRAP virtual double getThreshold() const = 0; | ||
| 861 | + | ||
| 862 | + CV_WRAP virtual void setNOctaves(int octaves) = 0; | ||
| 863 | + CV_WRAP virtual int getNOctaves() const = 0; | ||
| 864 | + | ||
| 865 | + CV_WRAP virtual void setNOctaveLayers(int octaveLayers) = 0; | ||
| 866 | + CV_WRAP virtual int getNOctaveLayers() const = 0; | ||
| 867 | + | ||
| 868 | + CV_WRAP virtual void setDiffusivity(KAZE::DiffusivityType diff) = 0; | ||
| 869 | + CV_WRAP virtual KAZE::DiffusivityType getDiffusivity() const = 0; | ||
| 870 | + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; | ||
| 871 | +}; | ||
| 872 | + | ||
| 873 | +//! @} features2d_main | ||
| 874 | + | ||
| 875 | +/****************************************************************************************\ | ||
| 876 | +* Distance * | ||
| 877 | +\****************************************************************************************/ | ||
| 878 | + | ||
| 879 | +template<typename T> | ||
| 880 | +struct CV_EXPORTS Accumulator | ||
| 881 | +{ | ||
| 882 | + typedef T Type; | ||
| 883 | +}; | ||
| 884 | + | ||
| 885 | +template<> struct Accumulator<unsigned char> { typedef float Type; }; | ||
| 886 | +template<> struct Accumulator<unsigned short> { typedef float Type; }; | ||
| 887 | +template<> struct Accumulator<char> { typedef float Type; }; | ||
| 888 | +template<> struct Accumulator<short> { typedef float Type; }; | ||
| 889 | + | ||
| 890 | +/* | ||
| 891 | + * Squared Euclidean distance functor | ||
| 892 | + */ | ||
| 893 | +template<class T> | ||
| 894 | +struct CV_EXPORTS SL2 | ||
| 895 | +{ | ||
| 896 | + static const NormTypes normType = NORM_L2SQR; | ||
| 897 | + typedef T ValueType; | ||
| 898 | + typedef typename Accumulator<T>::Type ResultType; | ||
| 899 | + | ||
| 900 | + ResultType operator()( const T* a, const T* b, int size ) const | ||
| 901 | + { | ||
| 902 | + return normL2Sqr<ValueType, ResultType>(a, b, size); | ||
| 903 | + } | ||
| 904 | +}; | ||
| 905 | + | ||
| 906 | +/* | ||
| 907 | + * Euclidean distance functor | ||
| 908 | + */ | ||
| 909 | +template<class T> | ||
| 910 | +struct L2 | ||
| 911 | +{ | ||
| 912 | + static const NormTypes normType = NORM_L2; | ||
| 913 | + typedef T ValueType; | ||
| 914 | + typedef typename Accumulator<T>::Type ResultType; | ||
| 915 | + | ||
| 916 | + ResultType operator()( const T* a, const T* b, int size ) const | ||
| 917 | + { | ||
| 918 | + return (ResultType)std::sqrt((double)normL2Sqr<ValueType, ResultType>(a, b, size)); | ||
| 919 | + } | ||
| 920 | +}; | ||
| 921 | + | ||
| 922 | +/* | ||
| 923 | + * Manhattan distance (city block distance) functor | ||
| 924 | + */ | ||
| 925 | +template<class T> | ||
| 926 | +struct L1 | ||
| 927 | +{ | ||
| 928 | + static const NormTypes normType = NORM_L1; | ||
| 929 | + typedef T ValueType; | ||
| 930 | + typedef typename Accumulator<T>::Type ResultType; | ||
| 931 | + | ||
| 932 | + ResultType operator()( const T* a, const T* b, int size ) const | ||
| 933 | + { | ||
| 934 | + return normL1<ValueType, ResultType>(a, b, size); | ||
| 935 | + } | ||
| 936 | +}; | ||
| 937 | + | ||
| 938 | +/****************************************************************************************\ | ||
| 939 | +* DescriptorMatcher * | ||
| 940 | +\****************************************************************************************/ | ||
| 941 | + | ||
| 942 | +//! @addtogroup features2d_match | ||
| 943 | +//! @{ | ||
| 944 | + | ||
| 945 | +/** @brief Abstract base class for matching keypoint descriptors. | ||
| 946 | + | ||
| 947 | +It has two groups of match methods: for matching descriptors of an image with another image or with | ||
| 948 | +an image set. | ||
| 949 | + */ | ||
| 950 | +class CV_EXPORTS_W DescriptorMatcher : public Algorithm | ||
| 951 | +{ | ||
| 952 | +public: | ||
| 953 | + enum MatcherType | ||
| 954 | + { | ||
| 955 | + FLANNBASED = 1, | ||
| 956 | + BRUTEFORCE = 2, | ||
| 957 | + BRUTEFORCE_L1 = 3, | ||
| 958 | + BRUTEFORCE_HAMMING = 4, | ||
| 959 | + BRUTEFORCE_HAMMINGLUT = 5, | ||
| 960 | + BRUTEFORCE_SL2 = 6 | ||
| 961 | + }; | ||
| 962 | + | ||
| 963 | + virtual ~DescriptorMatcher(); | ||
| 964 | + | ||
| 965 | + /** @brief Adds descriptors to train a CPU(trainDescCollectionis) or GPU(utrainDescCollectionis) descriptor | ||
| 966 | + collection. | ||
| 967 | + | ||
| 968 | + If the collection is not empty, the new descriptors are added to existing train descriptors. | ||
| 969 | + | ||
| 970 | + @param descriptors Descriptors to add. Each descriptors[i] is a set of descriptors from the same | ||
| 971 | + train image. | ||
| 972 | + */ | ||
| 973 | + CV_WRAP virtual void add( InputArrayOfArrays descriptors ); | ||
| 974 | + | ||
| 975 | + /** @brief Returns a constant link to the train descriptor collection trainDescCollection . | ||
| 976 | + */ | ||
| 977 | + CV_WRAP const std::vector<Mat>& getTrainDescriptors() const; | ||
| 978 | + | ||
| 979 | + /** @brief Clears the train descriptor collections. | ||
| 980 | + */ | ||
| 981 | + CV_WRAP virtual void clear() CV_OVERRIDE; | ||
| 982 | + | ||
| 983 | + /** @brief Returns true if there are no train descriptors in the both collections. | ||
| 984 | + */ | ||
| 985 | + CV_WRAP virtual bool empty() const CV_OVERRIDE; | ||
| 986 | + | ||
| 987 | + /** @brief Returns true if the descriptor matcher supports masking permissible matches. | ||
| 988 | + */ | ||
| 989 | + CV_WRAP virtual bool isMaskSupported() const = 0; | ||
| 990 | + | ||
| 991 | + /** @brief Trains a descriptor matcher | ||
| 992 | + | ||
| 993 | + Trains a descriptor matcher (for example, the flann index). In all methods to match, the method | ||
| 994 | + train() is run every time before matching. Some descriptor matchers (for example, BruteForceMatcher) | ||
| 995 | + have an empty implementation of this method. Other matchers really train their inner structures (for | ||
| 996 | + example, FlannBasedMatcher trains flann::Index ). | ||
| 997 | + */ | ||
| 998 | + CV_WRAP virtual void train(); | ||
| 999 | + | ||
| 1000 | + /** @brief Finds the best match for each descriptor from a query set. | ||
| 1001 | + | ||
| 1002 | + @param queryDescriptors Query set of descriptors. | ||
| 1003 | + @param trainDescriptors Train set of descriptors. This set is not added to the train descriptors | ||
| 1004 | + collection stored in the class object. | ||
| 1005 | + @param matches Matches. If a query descriptor is masked out in mask , no match is added for this | ||
| 1006 | + descriptor. So, matches size may be smaller than the query descriptors count. | ||
| 1007 | + @param mask Mask specifying permissible matches between an input query and train matrices of | ||
| 1008 | + descriptors. | ||
| 1009 | + | ||
| 1010 | + In the first variant of this method, the train descriptors are passed as an input argument. In the | ||
| 1011 | + second variant of the method, train descriptors collection that was set by DescriptorMatcher::add is | ||
| 1012 | + used. Optional mask (or masks) can be passed to specify which query and training descriptors can be | ||
| 1013 | + matched. Namely, queryDescriptors[i] can be matched with trainDescriptors[j] only if | ||
| 1014 | + mask.at\<uchar\>(i,j) is non-zero. | ||
| 1015 | + */ | ||
| 1016 | + CV_WRAP void match( InputArray queryDescriptors, InputArray trainDescriptors, | ||
| 1017 | + CV_OUT std::vector<DMatch>& matches, InputArray mask=noArray() ) const; | ||
| 1018 | + | ||
| 1019 | + /** @brief Finds the k best matches for each descriptor from a query set. | ||
| 1020 | + | ||
| 1021 | + @param queryDescriptors Query set of descriptors. | ||
| 1022 | + @param trainDescriptors Train set of descriptors. This set is not added to the train descriptors | ||
| 1023 | + collection stored in the class object. | ||
| 1024 | + @param mask Mask specifying permissible matches between an input query and train matrices of | ||
| 1025 | + descriptors. | ||
| 1026 | + @param matches Matches. Each matches[i] is k or less matches for the same query descriptor. | ||
| 1027 | + @param k Count of best matches found per each query descriptor or less if a query descriptor has | ||
| 1028 | + less than k possible matches in total. | ||
| 1029 | + @param compactResult Parameter used when the mask (or masks) is not empty. If compactResult is | ||
| 1030 | + false, the matches vector has the same size as queryDescriptors rows. If compactResult is true, | ||
| 1031 | + the matches vector does not contain matches for fully masked-out query descriptors. | ||
| 1032 | + | ||
| 1033 | + These extended variants of DescriptorMatcher::match methods find several best matches for each query | ||
| 1034 | + descriptor. The matches are returned in the distance increasing order. See DescriptorMatcher::match | ||
| 1035 | + for the details about query and train descriptors. | ||
| 1036 | + */ | ||
| 1037 | + CV_WRAP void knnMatch( InputArray queryDescriptors, InputArray trainDescriptors, | ||
| 1038 | + CV_OUT std::vector<std::vector<DMatch> >& matches, int k, | ||
| 1039 | + InputArray mask=noArray(), bool compactResult=false ) const; | ||
| 1040 | + | ||
| 1041 | + /** @brief For each query descriptor, finds the training descriptors not farther than the specified distance. | ||
| 1042 | + | ||
| 1043 | + @param queryDescriptors Query set of descriptors. | ||
| 1044 | + @param trainDescriptors Train set of descriptors. This set is not added to the train descriptors | ||
| 1045 | + collection stored in the class object. | ||
| 1046 | + @param matches Found matches. | ||
| 1047 | + @param compactResult Parameter used when the mask (or masks) is not empty. If compactResult is | ||
| 1048 | + false, the matches vector has the same size as queryDescriptors rows. If compactResult is true, | ||
| 1049 | + the matches vector does not contain matches for fully masked-out query descriptors. | ||
| 1050 | + @param maxDistance Threshold for the distance between matched descriptors. Distance means here | ||
| 1051 | + metric distance (e.g. Hamming distance), not the distance between coordinates (which is measured | ||
| 1052 | + in Pixels)! | ||
| 1053 | + @param mask Mask specifying permissible matches between an input query and train matrices of | ||
| 1054 | + descriptors. | ||
| 1055 | + | ||
| 1056 | + For each query descriptor, the methods find such training descriptors that the distance between the | ||
| 1057 | + query descriptor and the training descriptor is equal or smaller than maxDistance. Found matches are | ||
| 1058 | + returned in the distance increasing order. | ||
| 1059 | + */ | ||
| 1060 | + CV_WRAP void radiusMatch( InputArray queryDescriptors, InputArray trainDescriptors, | ||
| 1061 | + CV_OUT std::vector<std::vector<DMatch> >& matches, float maxDistance, | ||
| 1062 | + InputArray mask=noArray(), bool compactResult=false ) const; | ||
| 1063 | + | ||
| 1064 | + /** @overload | ||
| 1065 | + @param queryDescriptors Query set of descriptors. | ||
| 1066 | + @param matches Matches. If a query descriptor is masked out in mask , no match is added for this | ||
| 1067 | + descriptor. So, matches size may be smaller than the query descriptors count. | ||
| 1068 | + @param masks Set of masks. Each masks[i] specifies permissible matches between the input query | ||
| 1069 | + descriptors and stored train descriptors from the i-th image trainDescCollection[i]. | ||
| 1070 | + */ | ||
| 1071 | + CV_WRAP void match( InputArray queryDescriptors, CV_OUT std::vector<DMatch>& matches, | ||
| 1072 | + InputArrayOfArrays masks=noArray() ); | ||
| 1073 | + /** @overload | ||
| 1074 | + @param queryDescriptors Query set of descriptors. | ||
| 1075 | + @param matches Matches. Each matches[i] is k or less matches for the same query descriptor. | ||
| 1076 | + @param k Count of best matches found per each query descriptor or less if a query descriptor has | ||
| 1077 | + less than k possible matches in total. | ||
| 1078 | + @param masks Set of masks. Each masks[i] specifies permissible matches between the input query | ||
| 1079 | + descriptors and stored train descriptors from the i-th image trainDescCollection[i]. | ||
| 1080 | + @param compactResult Parameter used when the mask (or masks) is not empty. If compactResult is | ||
| 1081 | + false, the matches vector has the same size as queryDescriptors rows. If compactResult is true, | ||
| 1082 | + the matches vector does not contain matches for fully masked-out query descriptors. | ||
| 1083 | + */ | ||
| 1084 | + CV_WRAP void knnMatch( InputArray queryDescriptors, CV_OUT std::vector<std::vector<DMatch> >& matches, int k, | ||
| 1085 | + InputArrayOfArrays masks=noArray(), bool compactResult=false ); | ||
| 1086 | + /** @overload | ||
| 1087 | + @param queryDescriptors Query set of descriptors. | ||
| 1088 | + @param matches Found matches. | ||
| 1089 | + @param maxDistance Threshold for the distance between matched descriptors. Distance means here | ||
| 1090 | + metric distance (e.g. Hamming distance), not the distance between coordinates (which is measured | ||
| 1091 | + in Pixels)! | ||
| 1092 | + @param masks Set of masks. Each masks[i] specifies permissible matches between the input query | ||
| 1093 | + descriptors and stored train descriptors from the i-th image trainDescCollection[i]. | ||
| 1094 | + @param compactResult Parameter used when the mask (or masks) is not empty. If compactResult is | ||
| 1095 | + false, the matches vector has the same size as queryDescriptors rows. If compactResult is true, | ||
| 1096 | + the matches vector does not contain matches for fully masked-out query descriptors. | ||
| 1097 | + */ | ||
| 1098 | + CV_WRAP void radiusMatch( InputArray queryDescriptors, CV_OUT std::vector<std::vector<DMatch> >& matches, float maxDistance, | ||
| 1099 | + InputArrayOfArrays masks=noArray(), bool compactResult=false ); | ||
| 1100 | + | ||
| 1101 | + | ||
| 1102 | + CV_WRAP void write( const String& fileName ) const | ||
| 1103 | + { | ||
| 1104 | + FileStorage fs(fileName, FileStorage::WRITE); | ||
| 1105 | + write(fs); | ||
| 1106 | + } | ||
| 1107 | + | ||
| 1108 | + CV_WRAP void read( const String& fileName ) | ||
| 1109 | + { | ||
| 1110 | + FileStorage fs(fileName, FileStorage::READ); | ||
| 1111 | + read(fs.root()); | ||
| 1112 | + } | ||
| 1113 | + // Reads matcher object from a file node | ||
| 1114 | + // see corresponding cv::Algorithm method | ||
| 1115 | + CV_WRAP virtual void read( const FileNode& ) CV_OVERRIDE; | ||
| 1116 | + // Writes matcher object to a file storage | ||
| 1117 | + virtual void write( FileStorage& ) const CV_OVERRIDE; | ||
| 1118 | + | ||
| 1119 | + /** @brief Clones the matcher. | ||
| 1120 | + | ||
| 1121 | + @param emptyTrainData If emptyTrainData is false, the method creates a deep copy of the object, | ||
| 1122 | + that is, copies both parameters and train data. If emptyTrainData is true, the method creates an | ||
| 1123 | + object copy with the current parameters but with empty train data. | ||
| 1124 | + */ | ||
| 1125 | + CV_WRAP virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const = 0; | ||
| 1126 | + | ||
| 1127 | + /** @brief Creates a descriptor matcher of a given type with the default parameters (using default | ||
| 1128 | + constructor). | ||
| 1129 | + | ||
| 1130 | + @param descriptorMatcherType Descriptor matcher type. Now the following matcher types are | ||
| 1131 | + supported: | ||
| 1132 | + - `BruteForce` (it uses L2 ) | ||
| 1133 | + - `BruteForce-L1` | ||
| 1134 | + - `BruteForce-Hamming` | ||
| 1135 | + - `BruteForce-Hamming(2)` | ||
| 1136 | + - `FlannBased` | ||
| 1137 | + */ | ||
| 1138 | + CV_WRAP static Ptr<DescriptorMatcher> create( const String& descriptorMatcherType ); | ||
| 1139 | + | ||
| 1140 | + CV_WRAP static Ptr<DescriptorMatcher> create( const DescriptorMatcher::MatcherType& matcherType ); | ||
| 1141 | + | ||
| 1142 | + | ||
| 1143 | + // see corresponding cv::Algorithm method | ||
| 1144 | + CV_WRAP inline void write(const Ptr<FileStorage>& fs, const String& name = String()) const { Algorithm::write(fs, name); } | ||
| 1145 | + | ||
| 1146 | +protected: | ||
| 1147 | + /** | ||
| 1148 | + * Class to work with descriptors from several images as with one merged matrix. | ||
| 1149 | + * It is used e.g. in FlannBasedMatcher. | ||
| 1150 | + */ | ||
| 1151 | + class CV_EXPORTS DescriptorCollection | ||
| 1152 | + { | ||
| 1153 | + public: | ||
| 1154 | + DescriptorCollection(); | ||
| 1155 | + DescriptorCollection( const DescriptorCollection& collection ); | ||
| 1156 | + virtual ~DescriptorCollection(); | ||
| 1157 | + | ||
| 1158 | + // Vector of matrices "descriptors" will be merged to one matrix "mergedDescriptors" here. | ||
| 1159 | + void set( const std::vector<Mat>& descriptors ); | ||
| 1160 | + virtual void clear(); | ||
| 1161 | + | ||
| 1162 | + const Mat& getDescriptors() const; | ||
| 1163 | + const Mat getDescriptor( int imgIdx, int localDescIdx ) const; | ||
| 1164 | + const Mat getDescriptor( int globalDescIdx ) const; | ||
| 1165 | + void getLocalIdx( int globalDescIdx, int& imgIdx, int& localDescIdx ) const; | ||
| 1166 | + | ||
| 1167 | + int size() const; | ||
| 1168 | + | ||
| 1169 | + protected: | ||
| 1170 | + Mat mergedDescriptors; | ||
| 1171 | + std::vector<int> startIdxs; | ||
| 1172 | + }; | ||
| 1173 | + | ||
| 1174 | + //! In fact the matching is implemented only by the following two methods. These methods suppose | ||
| 1175 | + //! that the class object has been trained already. Public match methods call these methods | ||
| 1176 | + //! after calling train(). | ||
| 1177 | + virtual void knnMatchImpl( InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, int k, | ||
| 1178 | + InputArrayOfArrays masks=noArray(), bool compactResult=false ) = 0; | ||
| 1179 | + virtual void radiusMatchImpl( InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, float maxDistance, | ||
| 1180 | + InputArrayOfArrays masks=noArray(), bool compactResult=false ) = 0; | ||
| 1181 | + | ||
| 1182 | + static bool isPossibleMatch( InputArray mask, int queryIdx, int trainIdx ); | ||
| 1183 | + static bool isMaskedOut( InputArrayOfArrays masks, int queryIdx ); | ||
| 1184 | + | ||
| 1185 | + static Mat clone_op( Mat m ) { return m.clone(); } | ||
| 1186 | + void checkMasks( InputArrayOfArrays masks, int queryDescriptorsCount ) const; | ||
| 1187 | + | ||
| 1188 | + //! Collection of descriptors from train images. | ||
| 1189 | + std::vector<Mat> trainDescCollection; | ||
| 1190 | + std::vector<UMat> utrainDescCollection; | ||
| 1191 | +}; | ||
| 1192 | + | ||
| 1193 | +/** @brief Brute-force descriptor matcher. | ||
| 1194 | + | ||
| 1195 | +For each descriptor in the first set, this matcher finds the closest descriptor in the second set | ||
| 1196 | +by trying each one. This descriptor matcher supports masking permissible matches of descriptor | ||
| 1197 | +sets. | ||
| 1198 | + */ | ||
| 1199 | +class CV_EXPORTS_W BFMatcher : public DescriptorMatcher | ||
| 1200 | +{ | ||
| 1201 | +public: | ||
| 1202 | + /** @brief Brute-force matcher constructor (obsolete). Please use BFMatcher.create() | ||
| 1203 | + * | ||
| 1204 | + * | ||
| 1205 | + */ | ||
| 1206 | + CV_WRAP BFMatcher( int normType=NORM_L2, bool crossCheck=false ); | ||
| 1207 | + | ||
| 1208 | + virtual ~BFMatcher() {} | ||
| 1209 | + | ||
| 1210 | + virtual bool isMaskSupported() const CV_OVERRIDE { return true; } | ||
| 1211 | + | ||
| 1212 | + /** @brief Brute-force matcher create method. | ||
| 1213 | + @param normType One of NORM_L1, NORM_L2, NORM_HAMMING, NORM_HAMMING2. L1 and L2 norms are | ||
| 1214 | + preferable choices for SIFT and SURF descriptors, NORM_HAMMING should be used with ORB, BRISK and | ||
| 1215 | + BRIEF, NORM_HAMMING2 should be used with ORB when WTA_K==3 or 4 (see ORB::ORB constructor | ||
| 1216 | + description). | ||
| 1217 | + @param crossCheck If it is false, this is will be default BFMatcher behaviour when it finds the k | ||
| 1218 | + nearest neighbors for each query descriptor. If crossCheck==true, then the knnMatch() method with | ||
| 1219 | + k=1 will only return pairs (i,j) such that for i-th query descriptor the j-th descriptor in the | ||
| 1220 | + matcher's collection is the nearest and vice versa, i.e. the BFMatcher will only return consistent | ||
| 1221 | + pairs. Such technique usually produces best results with minimal number of outliers when there are | ||
| 1222 | + enough matches. This is alternative to the ratio test, used by D. Lowe in SIFT paper. | ||
| 1223 | + */ | ||
| 1224 | + CV_WRAP static Ptr<BFMatcher> create( int normType=NORM_L2, bool crossCheck=false ) ; | ||
| 1225 | + | ||
| 1226 | + virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const CV_OVERRIDE; | ||
| 1227 | +protected: | ||
| 1228 | + virtual void knnMatchImpl( InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, int k, | ||
| 1229 | + InputArrayOfArrays masks=noArray(), bool compactResult=false ) CV_OVERRIDE; | ||
| 1230 | + virtual void radiusMatchImpl( InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, float maxDistance, | ||
| 1231 | + InputArrayOfArrays masks=noArray(), bool compactResult=false ) CV_OVERRIDE; | ||
| 1232 | + | ||
| 1233 | + int normType; | ||
| 1234 | + bool crossCheck; | ||
| 1235 | +}; | ||
| 1236 | + | ||
| 1237 | +#if defined(HAVE_OPENCV_FLANN) || defined(CV_DOXYGEN) | ||
| 1238 | + | ||
| 1239 | +/** @brief Flann-based descriptor matcher. | ||
| 1240 | + | ||
| 1241 | +This matcher trains cv::flann::Index on a train descriptor collection and calls its nearest search | ||
| 1242 | +methods to find the best matches. So, this matcher may be faster when matching a large train | ||
| 1243 | +collection than the brute force matcher. FlannBasedMatcher does not support masking permissible | ||
| 1244 | +matches of descriptor sets because flann::Index does not support this. : | ||
| 1245 | + */ | ||
| 1246 | +class CV_EXPORTS_W FlannBasedMatcher : public DescriptorMatcher | ||
| 1247 | +{ | ||
| 1248 | +public: | ||
| 1249 | + CV_WRAP FlannBasedMatcher( const Ptr<flann::IndexParams>& indexParams=makePtr<flann::KDTreeIndexParams>(), | ||
| 1250 | + const Ptr<flann::SearchParams>& searchParams=makePtr<flann::SearchParams>() ); | ||
| 1251 | + | ||
| 1252 | + virtual void add( InputArrayOfArrays descriptors ) CV_OVERRIDE; | ||
| 1253 | + virtual void clear() CV_OVERRIDE; | ||
| 1254 | + | ||
| 1255 | + // Reads matcher object from a file node | ||
| 1256 | + virtual void read( const FileNode& ) CV_OVERRIDE; | ||
| 1257 | + // Writes matcher object to a file storage | ||
| 1258 | + virtual void write( FileStorage& ) const CV_OVERRIDE; | ||
| 1259 | + | ||
| 1260 | + virtual void train() CV_OVERRIDE; | ||
| 1261 | + virtual bool isMaskSupported() const CV_OVERRIDE; | ||
| 1262 | + | ||
| 1263 | + CV_WRAP static Ptr<FlannBasedMatcher> create(); | ||
| 1264 | + | ||
| 1265 | + virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const CV_OVERRIDE; | ||
| 1266 | +protected: | ||
| 1267 | + static void convertToDMatches( const DescriptorCollection& descriptors, | ||
| 1268 | + const Mat& indices, const Mat& distances, | ||
| 1269 | + std::vector<std::vector<DMatch> >& matches ); | ||
| 1270 | + | ||
| 1271 | + virtual void knnMatchImpl( InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, int k, | ||
| 1272 | + InputArrayOfArrays masks=noArray(), bool compactResult=false ) CV_OVERRIDE; | ||
| 1273 | + virtual void radiusMatchImpl( InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, float maxDistance, | ||
| 1274 | + InputArrayOfArrays masks=noArray(), bool compactResult=false ) CV_OVERRIDE; | ||
| 1275 | + | ||
| 1276 | + Ptr<flann::IndexParams> indexParams; | ||
| 1277 | + Ptr<flann::SearchParams> searchParams; | ||
| 1278 | + Ptr<flann::Index> flannIndex; | ||
| 1279 | + | ||
| 1280 | + DescriptorCollection mergedDescriptors; | ||
| 1281 | + int addedDescCount; | ||
| 1282 | +}; | ||
| 1283 | + | ||
| 1284 | +#endif | ||
| 1285 | + | ||
| 1286 | +//! @} features2d_match | ||
| 1287 | + | ||
| 1288 | +/****************************************************************************************\ | ||
| 1289 | +* Drawing functions * | ||
| 1290 | +\****************************************************************************************/ | ||
| 1291 | + | ||
| 1292 | +//! @addtogroup features2d_draw | ||
| 1293 | +//! @{ | ||
| 1294 | + | ||
| 1295 | +enum struct DrawMatchesFlags | ||
| 1296 | +{ | ||
| 1297 | + DEFAULT = 0, //!< Output image matrix will be created (Mat::create), | ||
| 1298 | + //!< i.e. existing memory of output image may be reused. | ||
| 1299 | + //!< Two source image, matches and single keypoints will be drawn. | ||
| 1300 | + //!< For each keypoint only the center point will be drawn (without | ||
| 1301 | + //!< the circle around keypoint with keypoint size and orientation). | ||
| 1302 | + DRAW_OVER_OUTIMG = 1, //!< Output image matrix will not be created (Mat::create). | ||
| 1303 | + //!< Matches will be drawn on existing content of output image. | ||
| 1304 | + NOT_DRAW_SINGLE_POINTS = 2, //!< Single keypoints will not be drawn. | ||
| 1305 | + DRAW_RICH_KEYPOINTS = 4 //!< For each keypoint the circle around keypoint with keypoint size and | ||
| 1306 | + //!< orientation will be drawn. | ||
| 1307 | +}; | ||
| 1308 | +CV_ENUM_FLAGS(DrawMatchesFlags) | ||
| 1309 | + | ||
| 1310 | +/** @brief Draws keypoints. | ||
| 1311 | + | ||
| 1312 | +@param image Source image. | ||
| 1313 | +@param keypoints Keypoints from the source image. | ||
| 1314 | +@param outImage Output image. Its content depends on the flags value defining what is drawn in the | ||
| 1315 | +output image. See possible flags bit values below. | ||
| 1316 | +@param color Color of keypoints. | ||
| 1317 | +@param flags Flags setting drawing features. Possible flags bit values are defined by | ||
| 1318 | +DrawMatchesFlags. See details above in drawMatches . | ||
| 1319 | + | ||
| 1320 | +@note | ||
| 1321 | +For Python API, flags are modified as cv.DRAW_MATCHES_FLAGS_DEFAULT, | ||
| 1322 | +cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS, cv.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG, | ||
| 1323 | +cv.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS | ||
| 1324 | + */ | ||
| 1325 | +CV_EXPORTS_W void drawKeypoints( InputArray image, const std::vector<KeyPoint>& keypoints, InputOutputArray outImage, | ||
| 1326 | + const Scalar& color=Scalar::all(-1), DrawMatchesFlags flags=DrawMatchesFlags::DEFAULT ); | ||
| 1327 | + | ||
| 1328 | +/** @brief Draws the found matches of keypoints from two images. | ||
| 1329 | + | ||
| 1330 | +@param img1 First source image. | ||
| 1331 | +@param keypoints1 Keypoints from the first source image. | ||
| 1332 | +@param img2 Second source image. | ||
| 1333 | +@param keypoints2 Keypoints from the second source image. | ||
| 1334 | +@param matches1to2 Matches from the first image to the second one, which means that keypoints1[i] | ||
| 1335 | +has a corresponding point in keypoints2[matches[i]] . | ||
| 1336 | +@param outImg Output image. Its content depends on the flags value defining what is drawn in the | ||
| 1337 | +output image. See possible flags bit values below. | ||
| 1338 | +@param matchColor Color of matches (lines and connected keypoints). If matchColor==Scalar::all(-1) | ||
| 1339 | +, the color is generated randomly. | ||
| 1340 | +@param singlePointColor Color of single keypoints (circles), which means that keypoints do not | ||
| 1341 | +have the matches. If singlePointColor==Scalar::all(-1) , the color is generated randomly. | ||
| 1342 | +@param matchesMask Mask determining which matches are drawn. If the mask is empty, all matches are | ||
| 1343 | +drawn. | ||
| 1344 | +@param flags Flags setting drawing features. Possible flags bit values are defined by | ||
| 1345 | +DrawMatchesFlags. | ||
| 1346 | + | ||
| 1347 | +This function draws matches of keypoints from two images in the output image. Match is a line | ||
| 1348 | +connecting two keypoints (circles). See cv::DrawMatchesFlags. | ||
| 1349 | + */ | ||
| 1350 | +CV_EXPORTS_W void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1, | ||
| 1351 | + InputArray img2, const std::vector<KeyPoint>& keypoints2, | ||
| 1352 | + const std::vector<DMatch>& matches1to2, InputOutputArray outImg, | ||
| 1353 | + const Scalar& matchColor=Scalar::all(-1), const Scalar& singlePointColor=Scalar::all(-1), | ||
| 1354 | + const std::vector<char>& matchesMask=std::vector<char>(), DrawMatchesFlags flags=DrawMatchesFlags::DEFAULT ); | ||
| 1355 | + | ||
| 1356 | +/** @overload */ | ||
| 1357 | +CV_EXPORTS_AS(drawMatchesKnn) void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1, | ||
| 1358 | + InputArray img2, const std::vector<KeyPoint>& keypoints2, | ||
| 1359 | + const std::vector<std::vector<DMatch> >& matches1to2, InputOutputArray outImg, | ||
| 1360 | + const Scalar& matchColor=Scalar::all(-1), const Scalar& singlePointColor=Scalar::all(-1), | ||
| 1361 | + const std::vector<std::vector<char> >& matchesMask=std::vector<std::vector<char> >(), DrawMatchesFlags flags=DrawMatchesFlags::DEFAULT ); | ||
| 1362 | + | ||
| 1363 | +//! @} features2d_draw | ||
| 1364 | + | ||
| 1365 | +/****************************************************************************************\ | ||
| 1366 | +* Functions to evaluate the feature detectors and [generic] descriptor extractors * | ||
| 1367 | +\****************************************************************************************/ | ||
| 1368 | + | ||
| 1369 | +CV_EXPORTS void evaluateFeatureDetector( const Mat& img1, const Mat& img2, const Mat& H1to2, | ||
| 1370 | + std::vector<KeyPoint>* keypoints1, std::vector<KeyPoint>* keypoints2, | ||
| 1371 | + float& repeatability, int& correspCount, | ||
| 1372 | + const Ptr<FeatureDetector>& fdetector=Ptr<FeatureDetector>() ); | ||
| 1373 | + | ||
| 1374 | +CV_EXPORTS void computeRecallPrecisionCurve( const std::vector<std::vector<DMatch> >& matches1to2, | ||
| 1375 | + const std::vector<std::vector<uchar> >& correctMatches1to2Mask, | ||
| 1376 | + std::vector<Point2f>& recallPrecisionCurve ); | ||
| 1377 | + | ||
| 1378 | +CV_EXPORTS float getRecall( const std::vector<Point2f>& recallPrecisionCurve, float l_precision ); | ||
| 1379 | +CV_EXPORTS int getNearestPoint( const std::vector<Point2f>& recallPrecisionCurve, float l_precision ); | ||
| 1380 | + | ||
| 1381 | +/****************************************************************************************\ | ||
| 1382 | +* Bag of visual words * | ||
| 1383 | +\****************************************************************************************/ | ||
| 1384 | + | ||
| 1385 | +//! @addtogroup features2d_category | ||
| 1386 | +//! @{ | ||
| 1387 | + | ||
| 1388 | +/** @brief Abstract base class for training the *bag of visual words* vocabulary from a set of descriptors. | ||
| 1389 | + | ||
| 1390 | +For details, see, for example, *Visual Categorization with Bags of Keypoints* by Gabriella Csurka, | ||
| 1391 | +Christopher R. Dance, Lixin Fan, Jutta Willamowski, Cedric Bray, 2004. : | ||
| 1392 | + */ | ||
| 1393 | +class CV_EXPORTS_W BOWTrainer | ||
| 1394 | +{ | ||
| 1395 | +public: | ||
| 1396 | + BOWTrainer(); | ||
| 1397 | + virtual ~BOWTrainer(); | ||
| 1398 | + | ||
| 1399 | + /** @brief Adds descriptors to a training set. | ||
| 1400 | + | ||
| 1401 | + @param descriptors Descriptors to add to a training set. Each row of the descriptors matrix is a | ||
| 1402 | + descriptor. | ||
| 1403 | + | ||
| 1404 | + The training set is clustered using clustermethod to construct the vocabulary. | ||
| 1405 | + */ | ||
| 1406 | + CV_WRAP void add( const Mat& descriptors ); | ||
| 1407 | + | ||
| 1408 | + /** @brief Returns a training set of descriptors. | ||
| 1409 | + */ | ||
| 1410 | + CV_WRAP const std::vector<Mat>& getDescriptors() const; | ||
| 1411 | + | ||
| 1412 | + /** @brief Returns the count of all descriptors stored in the training set. | ||
| 1413 | + */ | ||
| 1414 | + CV_WRAP int descriptorsCount() const; | ||
| 1415 | + | ||
| 1416 | + CV_WRAP virtual void clear(); | ||
| 1417 | + | ||
| 1418 | + /** @overload */ | ||
| 1419 | + CV_WRAP virtual Mat cluster() const = 0; | ||
| 1420 | + | ||
| 1421 | + /** @brief Clusters train descriptors. | ||
| 1422 | + | ||
| 1423 | + @param descriptors Descriptors to cluster. Each row of the descriptors matrix is a descriptor. | ||
| 1424 | + Descriptors are not added to the inner train descriptor set. | ||
| 1425 | + | ||
| 1426 | + The vocabulary consists of cluster centers. So, this method returns the vocabulary. In the first | ||
| 1427 | + variant of the method, train descriptors stored in the object are clustered. In the second variant, | ||
| 1428 | + input descriptors are clustered. | ||
| 1429 | + */ | ||
| 1430 | + CV_WRAP virtual Mat cluster( const Mat& descriptors ) const = 0; | ||
| 1431 | + | ||
| 1432 | +protected: | ||
| 1433 | + std::vector<Mat> descriptors; | ||
| 1434 | + int size; | ||
| 1435 | +}; | ||
| 1436 | + | ||
| 1437 | +/** @brief kmeans -based class to train visual vocabulary using the *bag of visual words* approach. : | ||
| 1438 | + */ | ||
| 1439 | +class CV_EXPORTS_W BOWKMeansTrainer : public BOWTrainer | ||
| 1440 | +{ | ||
| 1441 | +public: | ||
| 1442 | + /** @brief The constructor. | ||
| 1443 | + | ||
| 1444 | + @see cv::kmeans | ||
| 1445 | + */ | ||
| 1446 | + CV_WRAP BOWKMeansTrainer( int clusterCount, const TermCriteria& termcrit=TermCriteria(), | ||
| 1447 | + int attempts=3, int flags=KMEANS_PP_CENTERS ); | ||
| 1448 | + virtual ~BOWKMeansTrainer(); | ||
| 1449 | + | ||
| 1450 | + // Returns trained vocabulary (i.e. cluster centers). | ||
| 1451 | + CV_WRAP virtual Mat cluster() const CV_OVERRIDE; | ||
| 1452 | + CV_WRAP virtual Mat cluster( const Mat& descriptors ) const CV_OVERRIDE; | ||
| 1453 | + | ||
| 1454 | +protected: | ||
| 1455 | + | ||
| 1456 | + int clusterCount; | ||
| 1457 | + TermCriteria termcrit; | ||
| 1458 | + int attempts; | ||
| 1459 | + int flags; | ||
| 1460 | +}; | ||
| 1461 | + | ||
| 1462 | +/** @brief Class to compute an image descriptor using the *bag of visual words*. | ||
| 1463 | + | ||
| 1464 | +Such a computation consists of the following steps: | ||
| 1465 | + | ||
| 1466 | +1. Compute descriptors for a given image and its keypoints set. | ||
| 1467 | +2. Find the nearest visual words from the vocabulary for each keypoint descriptor. | ||
| 1468 | +3. Compute the bag-of-words image descriptor as is a normalized histogram of vocabulary words | ||
| 1469 | +encountered in the image. The i-th bin of the histogram is a frequency of i-th word of the | ||
| 1470 | +vocabulary in the given image. | ||
| 1471 | + */ | ||
| 1472 | +class CV_EXPORTS_W BOWImgDescriptorExtractor | ||
| 1473 | +{ | ||
| 1474 | +public: | ||
| 1475 | + /** @brief The constructor. | ||
| 1476 | + | ||
| 1477 | + @param dextractor Descriptor extractor that is used to compute descriptors for an input image and | ||
| 1478 | + its keypoints. | ||
| 1479 | + @param dmatcher Descriptor matcher that is used to find the nearest word of the trained vocabulary | ||
| 1480 | + for each keypoint descriptor of the image. | ||
| 1481 | + */ | ||
| 1482 | + CV_WRAP BOWImgDescriptorExtractor( const Ptr<DescriptorExtractor>& dextractor, | ||
| 1483 | + const Ptr<DescriptorMatcher>& dmatcher ); | ||
| 1484 | + /** @overload */ | ||
| 1485 | + BOWImgDescriptorExtractor( const Ptr<DescriptorMatcher>& dmatcher ); | ||
| 1486 | + virtual ~BOWImgDescriptorExtractor(); | ||
| 1487 | + | ||
| 1488 | + /** @brief Sets a visual vocabulary. | ||
| 1489 | + | ||
| 1490 | + @param vocabulary Vocabulary (can be trained using the inheritor of BOWTrainer ). Each row of the | ||
| 1491 | + vocabulary is a visual word (cluster center). | ||
| 1492 | + */ | ||
| 1493 | + CV_WRAP void setVocabulary( const Mat& vocabulary ); | ||
| 1494 | + | ||
| 1495 | + /** @brief Returns the set vocabulary. | ||
| 1496 | + */ | ||
| 1497 | + CV_WRAP const Mat& getVocabulary() const; | ||
| 1498 | + | ||
| 1499 | + /** @brief Computes an image descriptor using the set visual vocabulary. | ||
| 1500 | + | ||
| 1501 | + @param image Image, for which the descriptor is computed. | ||
| 1502 | + @param keypoints Keypoints detected in the input image. | ||
| 1503 | + @param imgDescriptor Computed output image descriptor. | ||
| 1504 | + @param pointIdxsOfClusters Indices of keypoints that belong to the cluster. This means that | ||
| 1505 | + pointIdxsOfClusters[i] are keypoint indices that belong to the i -th cluster (word of vocabulary) | ||
| 1506 | + returned if it is non-zero. | ||
| 1507 | + @param descriptors Descriptors of the image keypoints that are returned if they are non-zero. | ||
| 1508 | + */ | ||
| 1509 | + void compute( InputArray image, std::vector<KeyPoint>& keypoints, OutputArray imgDescriptor, | ||
| 1510 | + std::vector<std::vector<int> >* pointIdxsOfClusters=0, Mat* descriptors=0 ); | ||
| 1511 | + /** @overload | ||
| 1512 | + @param keypointDescriptors Computed descriptors to match with vocabulary. | ||
| 1513 | + @param imgDescriptor Computed output image descriptor. | ||
| 1514 | + @param pointIdxsOfClusters Indices of keypoints that belong to the cluster. This means that | ||
| 1515 | + pointIdxsOfClusters[i] are keypoint indices that belong to the i -th cluster (word of vocabulary) | ||
| 1516 | + returned if it is non-zero. | ||
| 1517 | + */ | ||
| 1518 | + void compute( InputArray keypointDescriptors, OutputArray imgDescriptor, | ||
| 1519 | + std::vector<std::vector<int> >* pointIdxsOfClusters=0 ); | ||
| 1520 | + // compute() is not constant because DescriptorMatcher::match is not constant | ||
| 1521 | + | ||
| 1522 | + CV_WRAP_AS(compute) void compute2( const Mat& image, std::vector<KeyPoint>& keypoints, CV_OUT Mat& imgDescriptor ) | ||
| 1523 | + { compute(image,keypoints,imgDescriptor); } | ||
| 1524 | + | ||
| 1525 | + /** @brief Returns an image descriptor size if the vocabulary is set. Otherwise, it returns 0. | ||
| 1526 | + */ | ||
| 1527 | + CV_WRAP int descriptorSize() const; | ||
| 1528 | + | ||
| 1529 | + /** @brief Returns an image descriptor type. | ||
| 1530 | + */ | ||
| 1531 | + CV_WRAP int descriptorType() const; | ||
| 1532 | + | ||
| 1533 | +protected: | ||
| 1534 | + Mat vocabulary; | ||
| 1535 | + Ptr<DescriptorExtractor> dextractor; | ||
| 1536 | + Ptr<DescriptorMatcher> dmatcher; | ||
| 1537 | +}; | ||
| 1538 | + | ||
| 1539 | +//! @} features2d_category | ||
| 1540 | + | ||
| 1541 | +//! @} features2d | ||
| 1542 | + | ||
| 1543 | +} /* namespace cv */ | ||
| 1544 | + | ||
| 1545 | +#endif |
| 1 | +/*M/////////////////////////////////////////////////////////////////////////////////////// | ||
| 2 | +// | ||
| 3 | +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. | ||
| 4 | +// | ||
| 5 | +// By downloading, copying, installing or using the software you agree to this license. | ||
| 6 | +// If you do not agree to this license, do not download, install, | ||
| 7 | +// copy or use the software. | ||
| 8 | +// | ||
| 9 | +// | ||
| 10 | +// License Agreement | ||
| 11 | +// For Open Source Computer Vision Library | ||
| 12 | +// | ||
| 13 | +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. | ||
| 14 | +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. | ||
| 15 | +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. | ||
| 16 | +// Third party copyrights are property of their respective owners. | ||
| 17 | +// | ||
| 18 | +// Redistribution and use in source and binary forms, with or without modification, | ||
| 19 | +// are permitted provided that the following conditions are met: | ||
| 20 | +// | ||
| 21 | +// * Redistribution's of source code must retain the above copyright notice, | ||
| 22 | +// this list of conditions and the following disclaimer. | ||
| 23 | +// | ||
| 24 | +// * Redistribution's in binary form must reproduce the above copyright notice, | ||
| 25 | +// this list of conditions and the following disclaimer in the documentation | ||
| 26 | +// and/or other materials provided with the distribution. | ||
| 27 | +// | ||
| 28 | +// * The name of the copyright holders may not be used to endorse or promote products | ||
| 29 | +// derived from this software without specific prior written permission. | ||
| 30 | +// | ||
| 31 | +// This software is provided by the copyright holders and contributors "as is" and | ||
| 32 | +// any express or implied warranties, including, but not limited to, the implied | ||
| 33 | +// warranties of merchantability and fitness for a particular purpose are disclaimed. | ||
| 34 | +// In no event shall the Intel Corporation or contributors be liable for any direct, | ||
| 35 | +// indirect, incidental, special, exemplary, or consequential damages | ||
| 36 | +// (including, but not limited to, procurement of substitute goods or services; | ||
| 37 | +// loss of use, data, or profits; or business interruption) however caused | ||
| 38 | +// and on any theory of liability, whether in contract, strict liability, | ||
| 39 | +// or tort (including negligence or otherwise) arising in any way out of | ||
| 40 | +// the use of this software, even if advised of the possibility of such damage. | ||
| 41 | +// | ||
| 42 | +//M*/ | ||
| 43 | + | ||
| 44 | +#ifdef __OPENCV_BUILD | ||
| 45 | +#error this is a compatibility header which should not be used inside the OpenCV library | ||
| 46 | +#endif | ||
| 47 | + | ||
| 48 | +#include "opencv2/features2d.hpp" |
| 1 | +#ifndef OPENCV_FEATURE2D_HAL_INTERFACE_H | ||
| 2 | +#define OPENCV_FEATURE2D_HAL_INTERFACE_H | ||
| 3 | + | ||
| 4 | +#include "opencv2/core/cvdef.h" | ||
| 5 | +//! @addtogroup features2d_hal_interface | ||
| 6 | +//! @{ | ||
| 7 | + | ||
| 8 | +//! @name Fast feature detector types | ||
| 9 | +//! @sa cv::FastFeatureDetector | ||
| 10 | +//! @{ | ||
| 11 | +#define CV_HAL_TYPE_5_8 0 | ||
| 12 | +#define CV_HAL_TYPE_7_12 1 | ||
| 13 | +#define CV_HAL_TYPE_9_16 2 | ||
| 14 | +//! @} | ||
| 15 | + | ||
| 16 | +//! @name Key point | ||
| 17 | +//! @sa cv::KeyPoint | ||
| 18 | +//! @{ | ||
| 19 | +struct CV_EXPORTS cvhalKeyPoint | ||
| 20 | +{ | ||
| 21 | + float x; | ||
| 22 | + float y; | ||
| 23 | + float size; | ||
| 24 | + float angle; | ||
| 25 | + float response; | ||
| 26 | + int octave; | ||
| 27 | + int class_id; | ||
| 28 | +}; | ||
| 29 | +//! @} | ||
| 30 | + | ||
| 31 | +//! @} | ||
| 32 | + | ||
| 33 | +#endif |
lite.ai.toolkit/include/opencv2/flann.hpp
0 → 100644
| 1 | +/*M/////////////////////////////////////////////////////////////////////////////////////// | ||
| 2 | +// | ||
| 3 | +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. | ||
| 4 | +// | ||
| 5 | +// By downloading, copying, installing or using the software you agree to this license. | ||
| 6 | +// If you do not agree to this license, do not download, install, | ||
| 7 | +// copy or use the software. | ||
| 8 | +// | ||
| 9 | +// | ||
| 10 | +// License Agreement | ||
| 11 | +// For Open Source Computer Vision Library | ||
| 12 | +// | ||
| 13 | +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. | ||
| 14 | +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. | ||
| 15 | +// Third party copyrights are property of their respective owners. | ||
| 16 | +// | ||
| 17 | +// Redistribution and use in source and binary forms, with or without modification, | ||
| 18 | +// are permitted provided that the following conditions are met: | ||
| 19 | +// | ||
| 20 | +// * Redistribution's of source code must retain the above copyright notice, | ||
| 21 | +// this list of conditions and the following disclaimer. | ||
| 22 | +// | ||
| 23 | +// * Redistribution's in binary form must reproduce the above copyright notice, | ||
| 24 | +// this list of conditions and the following disclaimer in the documentation | ||
| 25 | +// and/or other materials provided with the distribution. | ||
| 26 | +// | ||
| 27 | +// * The name of the copyright holders may not be used to endorse or promote products | ||
| 28 | +// derived from this software without specific prior written permission. | ||
| 29 | +// | ||
| 30 | +// This software is provided by the copyright holders and contributors "as is" and | ||
| 31 | +// any express or implied warranties, including, but not limited to, the implied | ||
| 32 | +// warranties of merchantability and fitness for a particular purpose are disclaimed. | ||
| 33 | +// In no event shall the Intel Corporation or contributors be liable for any direct, | ||
| 34 | +// indirect, incidental, special, exemplary, or consequential damages | ||
| 35 | +// (including, but not limited to, procurement of substitute goods or services; | ||
| 36 | +// loss of use, data, or profits; or business interruption) however caused | ||
| 37 | +// and on any theory of liability, whether in contract, strict liability, | ||
| 38 | +// or tort (including negligence or otherwise) arising in any way out of | ||
| 39 | +// the use of this software, even if advised of the possibility of such damage. | ||
| 40 | +// | ||
| 41 | +//M*/ | ||
| 42 | + | ||
| 43 | +#ifndef OPENCV_FLANN_HPP | ||
| 44 | +#define OPENCV_FLANN_HPP | ||
| 45 | + | ||
| 46 | +#include "opencv2/core.hpp" | ||
| 47 | +#include "opencv2/flann/miniflann.hpp" | ||
| 48 | +#include "opencv2/flann/flann_base.hpp" | ||
| 49 | + | ||
| 50 | +/** | ||
| 51 | +@defgroup flann Clustering and Search in Multi-Dimensional Spaces | ||
| 52 | + | ||
| 53 | +This section documents OpenCV's interface to the FLANN library. FLANN (Fast Library for Approximate | ||
| 54 | +Nearest Neighbors) is a library that contains a collection of algorithms optimized for fast nearest | ||
| 55 | +neighbor search in large datasets and for high dimensional features. More information about FLANN | ||
| 56 | +can be found in @cite Muja2009 . | ||
| 57 | +*/ | ||
| 58 | + | ||
| 59 | +namespace cvflann | ||
| 60 | +{ | ||
| 61 | + CV_EXPORTS flann_distance_t flann_distance_type(); | ||
| 62 | + CV_DEPRECATED CV_EXPORTS void set_distance_type(flann_distance_t distance_type, int order); | ||
| 63 | +} | ||
| 64 | + | ||
| 65 | + | ||
| 66 | +namespace cv | ||
| 67 | +{ | ||
| 68 | +namespace flann | ||
| 69 | +{ | ||
| 70 | + | ||
| 71 | + | ||
| 72 | +//! @addtogroup flann | ||
| 73 | +//! @{ | ||
| 74 | + | ||
| 75 | +template <typename T> struct CvType {}; | ||
| 76 | +template <> struct CvType<unsigned char> { static int type() { return CV_8U; } }; | ||
| 77 | +template <> struct CvType<char> { static int type() { return CV_8S; } }; | ||
| 78 | +template <> struct CvType<unsigned short> { static int type() { return CV_16U; } }; | ||
| 79 | +template <> struct CvType<short> { static int type() { return CV_16S; } }; | ||
| 80 | +template <> struct CvType<int> { static int type() { return CV_32S; } }; | ||
| 81 | +template <> struct CvType<float> { static int type() { return CV_32F; } }; | ||
| 82 | +template <> struct CvType<double> { static int type() { return CV_64F; } }; | ||
| 83 | + | ||
| 84 | + | ||
| 85 | +// bring the flann parameters into this namespace | ||
| 86 | +using ::cvflann::get_param; | ||
| 87 | +using ::cvflann::print_params; | ||
| 88 | + | ||
| 89 | +// bring the flann distances into this namespace | ||
| 90 | +using ::cvflann::L2_Simple; | ||
| 91 | +using ::cvflann::L2; | ||
| 92 | +using ::cvflann::L1; | ||
| 93 | +using ::cvflann::MinkowskiDistance; | ||
| 94 | +using ::cvflann::MaxDistance; | ||
| 95 | +using ::cvflann::HammingLUT; | ||
| 96 | +using ::cvflann::Hamming; | ||
| 97 | +using ::cvflann::Hamming2; | ||
| 98 | +using ::cvflann::DNAmmingLUT; | ||
| 99 | +using ::cvflann::DNAmming2; | ||
| 100 | +using ::cvflann::HistIntersectionDistance; | ||
| 101 | +using ::cvflann::HellingerDistance; | ||
| 102 | +using ::cvflann::ChiSquareDistance; | ||
| 103 | +using ::cvflann::KL_Divergence; | ||
| 104 | + | ||
| 105 | + | ||
| 106 | +/** @brief The FLANN nearest neighbor index class. This class is templated with the type of elements for which | ||
| 107 | +the index is built. | ||
| 108 | + | ||
| 109 | +`Distance` functor specifies the metric to be used to calculate the distance between two points. | ||
| 110 | +There are several `Distance` functors that are readily available: | ||
| 111 | + | ||
| 112 | +cv::cvflann::L2_Simple - Squared Euclidean distance functor. | ||
| 113 | +This is the simpler, unrolled version. This is preferable for very low dimensionality data (eg 3D points) | ||
| 114 | + | ||
| 115 | +cv::flann::L2 - Squared Euclidean distance functor, optimized version. | ||
| 116 | + | ||
| 117 | +cv::flann::L1 - Manhattan distance functor, optimized version. | ||
| 118 | + | ||
| 119 | +cv::flann::MinkowskiDistance - The Minkowsky distance functor. | ||
| 120 | +This is highly optimised with loop unrolling. | ||
| 121 | +The computation of squared root at the end is omitted for efficiency. | ||
| 122 | + | ||
| 123 | +cv::flann::MaxDistance - The max distance functor. It computes the | ||
| 124 | +maximum distance between two vectors. This distance is not a valid kdtree distance, it's not | ||
| 125 | +dimensionwise additive. | ||
| 126 | + | ||
| 127 | +cv::flann::HammingLUT - %Hamming distance functor. It counts the bit | ||
| 128 | +differences between two strings using a lookup table implementation. | ||
| 129 | + | ||
| 130 | +cv::flann::Hamming - %Hamming distance functor. Population count is | ||
| 131 | +performed using library calls, if available. Lookup table implementation is used as a fallback. | ||
| 132 | + | ||
| 133 | +cv::flann::Hamming2 - %Hamming distance functor. Population count is | ||
| 134 | +implemented in 12 arithmetic operations (one of which is multiplication). | ||
| 135 | + | ||
| 136 | +cv::flann::DNAmmingLUT - %Adaptation of the Hamming distance functor to DNA comparison. | ||
| 137 | +As the four bases A, C, G, T of the DNA (or A, G, C, U for RNA) can be coded on 2 bits, | ||
| 138 | +it counts the bits pairs differences between two sequences using a lookup table implementation. | ||
| 139 | + | ||
| 140 | +cv::flann::DNAmming2 - %Adaptation of the Hamming distance functor to DNA comparison. | ||
| 141 | +Bases differences count are vectorised thanks to arithmetic operations using standard | ||
| 142 | +registers (AVX2 and AVX-512 should come in a near future). | ||
| 143 | + | ||
| 144 | +cv::flann::HistIntersectionDistance - The histogram | ||
| 145 | +intersection distance functor. | ||
| 146 | + | ||
| 147 | +cv::flann::HellingerDistance - The Hellinger distance functor. | ||
| 148 | + | ||
| 149 | +cv::flann::ChiSquareDistance - The chi-square distance functor. | ||
| 150 | + | ||
| 151 | +cv::flann::KL_Divergence - The Kullback-Leibler divergence functor. | ||
| 152 | + | ||
| 153 | +Although the provided implementations cover a vast range of cases, it is also possible to use | ||
| 154 | +a custom implementation. The distance functor is a class whose `operator()` computes the distance | ||
| 155 | +between two features. If the distance is also a kd-tree compatible distance, it should also provide an | ||
| 156 | +`accum_dist()` method that computes the distance between individual feature dimensions. | ||
| 157 | + | ||
| 158 | +In addition to `operator()` and `accum_dist()`, a distance functor should also define the | ||
| 159 | +`ElementType` and the `ResultType` as the types of the elements it operates on and the type of the | ||
| 160 | +result it computes. If a distance functor can be used as a kd-tree distance (meaning that the full | ||
| 161 | +distance between a pair of features can be accumulated from the partial distances between the | ||
| 162 | +individual dimensions) a typedef `is_kdtree_distance` should be present inside the distance functor. | ||
| 163 | +If the distance is not a kd-tree distance, but it's a distance in a vector space (the individual | ||
| 164 | +dimensions of the elements it operates on can be accessed independently) a typedef | ||
| 165 | +`is_vector_space_distance` should be defined inside the functor. If neither typedef is defined, the | ||
| 166 | +distance is assumed to be a metric distance and will only be used with indexes operating on | ||
| 167 | +generic metric distances. | ||
| 168 | + */ | ||
| 169 | +template <typename Distance> | ||
| 170 | +class GenericIndex | ||
| 171 | +{ | ||
| 172 | +public: | ||
| 173 | + typedef typename Distance::ElementType ElementType; | ||
| 174 | + typedef typename Distance::ResultType DistanceType; | ||
| 175 | + | ||
| 176 | + /** @brief Constructs a nearest neighbor search index for a given dataset. | ||
| 177 | + | ||
| 178 | + @param features Matrix of containing the features(points) to index. The size of the matrix is | ||
| 179 | + num_features x feature_dimensionality and the data type of the elements in the matrix must | ||
| 180 | + coincide with the type of the index. | ||
| 181 | + @param params Structure containing the index parameters. The type of index that will be | ||
| 182 | + constructed depends on the type of this parameter. See the description. | ||
| 183 | + @param distance | ||
| 184 | + | ||
| 185 | + The method constructs a fast search structure from a set of features using the specified algorithm | ||
| 186 | + with specified parameters, as defined by params. params is a reference to one of the following class | ||
| 187 | + IndexParams descendants: | ||
| 188 | + | ||
| 189 | + - **LinearIndexParams** When passing an object of this type, the index will perform a linear, | ||
| 190 | + brute-force search. : | ||
| 191 | + @code | ||
| 192 | + struct LinearIndexParams : public IndexParams | ||
| 193 | + { | ||
| 194 | + }; | ||
| 195 | + @endcode | ||
| 196 | + - **KDTreeIndexParams** When passing an object of this type the index constructed will consist of | ||
| 197 | + a set of randomized kd-trees which will be searched in parallel. : | ||
| 198 | + @code | ||
| 199 | + struct KDTreeIndexParams : public IndexParams | ||
| 200 | + { | ||
| 201 | + KDTreeIndexParams( int trees = 4 ); | ||
| 202 | + }; | ||
| 203 | + @endcode | ||
| 204 | + - **HierarchicalClusteringIndexParams** When passing an object of this type the index constructed | ||
| 205 | + will be a hierarchical tree of clusters, dividing each set of points into n clusters whose centers | ||
| 206 | + are picked among the points without further refinement of their position. | ||
| 207 | + This algorithm fits both floating, integer and binary vectors. : | ||
| 208 | + @code | ||
| 209 | + struct HierarchicalClusteringIndexParams : public IndexParams | ||
| 210 | + { | ||
| 211 | + HierarchicalClusteringIndexParams( | ||
| 212 | + int branching = 32, | ||
| 213 | + flann_centers_init_t centers_init = CENTERS_RANDOM, | ||
| 214 | + int trees = 4, | ||
| 215 | + int leaf_size = 100); | ||
| 216 | + | ||
| 217 | + }; | ||
| 218 | + @endcode | ||
| 219 | + - **KMeansIndexParams** When passing an object of this type the index constructed will be a | ||
| 220 | + hierarchical k-means tree (one tree by default), dividing each set of points into n clusters | ||
| 221 | + whose barycenters are refined iteratively. | ||
| 222 | + Note that this algorithm has been extended to the support of binary vectors as an alternative | ||
| 223 | + to LSH when knn search speed is the criterium. It will also outperform LSH when processing | ||
| 224 | + directly (i.e. without the use of MCA/PCA) datasets whose points share mostly the same values | ||
| 225 | + for most of the dimensions. It is recommended to set more than one tree with binary data. : | ||
| 226 | + @code | ||
| 227 | + struct KMeansIndexParams : public IndexParams | ||
| 228 | + { | ||
| 229 | + KMeansIndexParams( | ||
| 230 | + int branching = 32, | ||
| 231 | + int iterations = 11, | ||
| 232 | + flann_centers_init_t centers_init = CENTERS_RANDOM, | ||
| 233 | + float cb_index = 0.2, | ||
| 234 | + int trees = 1); | ||
| 235 | + }; | ||
| 236 | + @endcode | ||
| 237 | + - **CompositeIndexParams** When using a parameters object of this type the index created | ||
| 238 | + combines the randomized kd-trees and the hierarchical k-means tree. : | ||
| 239 | + @code | ||
| 240 | + struct CompositeIndexParams : public IndexParams | ||
| 241 | + { | ||
| 242 | + CompositeIndexParams( | ||
| 243 | + int trees = 4, | ||
| 244 | + int branching = 32, | ||
| 245 | + int iterations = 11, | ||
| 246 | + flann_centers_init_t centers_init = CENTERS_RANDOM, | ||
| 247 | + float cb_index = 0.2 ); | ||
| 248 | + }; | ||
| 249 | + @endcode | ||
| 250 | + - **LshIndexParams** When using a parameters object of this type the index created uses | ||
| 251 | + multi-probe LSH (by Multi-Probe LSH: Efficient Indexing for High-Dimensional Similarity Search | ||
| 252 | + by Qin Lv, William Josephson, Zhe Wang, Moses Charikar, Kai Li., Proceedings of the 33rd | ||
| 253 | + International Conference on Very Large Data Bases (VLDB). Vienna, Austria. September 2007). | ||
| 254 | + This algorithm is designed for binary vectors. : | ||
| 255 | + @code | ||
| 256 | + struct LshIndexParams : public IndexParams | ||
| 257 | + { | ||
| 258 | + LshIndexParams( | ||
| 259 | + int table_number, | ||
| 260 | + int key_size, | ||
| 261 | + int multi_probe_level ); | ||
| 262 | + }; | ||
| 263 | + @endcode | ||
| 264 | + - **AutotunedIndexParams** When passing an object of this type the index created is | ||
| 265 | + automatically tuned to offer the best performance, by choosing the optimal index type | ||
| 266 | + (randomized kd-trees, hierarchical kmeans, linear) and parameters for the dataset provided. : | ||
| 267 | + @code | ||
| 268 | + struct AutotunedIndexParams : public IndexParams | ||
| 269 | + { | ||
| 270 | + AutotunedIndexParams( | ||
| 271 | + float target_precision = 0.9, | ||
| 272 | + float build_weight = 0.01, | ||
| 273 | + float memory_weight = 0, | ||
| 274 | + float sample_fraction = 0.1 ); | ||
| 275 | + }; | ||
| 276 | + @endcode | ||
| 277 | + - **SavedIndexParams** This object type is used for loading a previously saved index from the | ||
| 278 | + disk. : | ||
| 279 | + @code | ||
| 280 | + struct SavedIndexParams : public IndexParams | ||
| 281 | + { | ||
| 282 | + SavedIndexParams( String filename ); | ||
| 283 | + }; | ||
| 284 | + @endcode | ||
| 285 | + */ | ||
| 286 | + GenericIndex(const Mat& features, const ::cvflann::IndexParams& params, Distance distance = Distance()); | ||
| 287 | + | ||
| 288 | + ~GenericIndex(); | ||
| 289 | + | ||
| 290 | + /** @brief Performs a K-nearest neighbor search for a given query point using the index. | ||
| 291 | + | ||
| 292 | + @param query The query point | ||
| 293 | + @param indices Vector that will contain the indices of the K-nearest neighbors found. It must have | ||
| 294 | + at least knn size. | ||
| 295 | + @param dists Vector that will contain the distances to the K-nearest neighbors found. It must have | ||
| 296 | + at least knn size. | ||
| 297 | + @param knn Number of nearest neighbors to search for. | ||
| 298 | + @param params SearchParams | ||
| 299 | + */ | ||
| 300 | + void knnSearch(const std::vector<ElementType>& query, std::vector<int>& indices, | ||
| 301 | + std::vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& params); | ||
| 302 | + void knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& params); | ||
| 303 | + | ||
| 304 | + /** @brief Performs a radius nearest neighbor search for a given query point using the index. | ||
| 305 | + | ||
| 306 | + @param query The query point. | ||
| 307 | + @param indices Vector that will contain the indices of the nearest neighbors found. | ||
| 308 | + @param dists Vector that will contain the distances to the nearest neighbors found. It has the same | ||
| 309 | + number of elements as indices. | ||
| 310 | + @param radius The search radius. | ||
| 311 | + @param params SearchParams | ||
| 312 | + | ||
| 313 | + This function returns the number of nearest neighbors found. | ||
| 314 | + */ | ||
| 315 | + int radiusSearch(const std::vector<ElementType>& query, std::vector<int>& indices, | ||
| 316 | + std::vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& params); | ||
| 317 | + int radiusSearch(const Mat& query, Mat& indices, Mat& dists, | ||
| 318 | + DistanceType radius, const ::cvflann::SearchParams& params); | ||
| 319 | + | ||
| 320 | + void save(String filename) { nnIndex->save(filename); } | ||
| 321 | + | ||
| 322 | + int veclen() const { return nnIndex->veclen(); } | ||
| 323 | + | ||
| 324 | + int size() const { return (int)nnIndex->size(); } | ||
| 325 | + | ||
| 326 | + ::cvflann::IndexParams getParameters() { return nnIndex->getParameters(); } | ||
| 327 | + | ||
| 328 | + CV_DEPRECATED const ::cvflann::IndexParams* getIndexParameters() { return nnIndex->getIndexParameters(); } | ||
| 329 | + | ||
| 330 | +private: | ||
| 331 | + ::cvflann::Index<Distance>* nnIndex; | ||
| 332 | + Mat _dataset; | ||
| 333 | +}; | ||
| 334 | + | ||
| 335 | +//! @cond IGNORED | ||
| 336 | + | ||
| 337 | +#define FLANN_DISTANCE_CHECK \ | ||
| 338 | + if ( ::cvflann::flann_distance_type() != cvflann::FLANN_DIST_L2) { \ | ||
| 339 | + printf("[WARNING] You are using cv::flann::Index (or cv::flann::GenericIndex) and have also changed "\ | ||
| 340 | + "the distance using cvflann::set_distance_type. This is no longer working as expected "\ | ||
| 341 | + "(cv::flann::Index always uses L2). You should create the index templated on the distance, "\ | ||
| 342 | + "for example for L1 distance use: GenericIndex< L1<float> > \n"); \ | ||
| 343 | + } | ||
| 344 | + | ||
| 345 | + | ||
| 346 | +template <typename Distance> | ||
| 347 | +GenericIndex<Distance>::GenericIndex(const Mat& dataset, const ::cvflann::IndexParams& params, Distance distance) | ||
| 348 | +: _dataset(dataset) | ||
| 349 | +{ | ||
| 350 | + CV_Assert(dataset.type() == CvType<ElementType>::type()); | ||
| 351 | + CV_Assert(dataset.isContinuous()); | ||
| 352 | + ::cvflann::Matrix<ElementType> m_dataset((ElementType*)_dataset.ptr<ElementType>(0), _dataset.rows, _dataset.cols); | ||
| 353 | + | ||
| 354 | + nnIndex = new ::cvflann::Index<Distance>(m_dataset, params, distance); | ||
| 355 | + | ||
| 356 | + FLANN_DISTANCE_CHECK | ||
| 357 | + | ||
| 358 | + nnIndex->buildIndex(); | ||
| 359 | +} | ||
| 360 | + | ||
| 361 | +template <typename Distance> | ||
| 362 | +GenericIndex<Distance>::~GenericIndex() | ||
| 363 | +{ | ||
| 364 | + delete nnIndex; | ||
| 365 | +} | ||
| 366 | + | ||
| 367 | +template <typename Distance> | ||
| 368 | +void GenericIndex<Distance>::knnSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& searchParams) | ||
| 369 | +{ | ||
| 370 | + ::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size()); | ||
| 371 | + ::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size()); | ||
| 372 | + ::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size()); | ||
| 373 | + | ||
| 374 | + FLANN_DISTANCE_CHECK | ||
| 375 | + | ||
| 376 | + nnIndex->knnSearch(m_query,m_indices,m_dists,knn,searchParams); | ||
| 377 | +} | ||
| 378 | + | ||
| 379 | + | ||
| 380 | +template <typename Distance> | ||
| 381 | +void GenericIndex<Distance>::knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& searchParams) | ||
| 382 | +{ | ||
| 383 | + CV_Assert(queries.type() == CvType<ElementType>::type()); | ||
| 384 | + CV_Assert(queries.isContinuous()); | ||
| 385 | + ::cvflann::Matrix<ElementType> m_queries((ElementType*)queries.ptr<ElementType>(0), queries.rows, queries.cols); | ||
| 386 | + | ||
| 387 | + CV_Assert(indices.type() == CV_32S); | ||
| 388 | + CV_Assert(indices.isContinuous()); | ||
| 389 | + ::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols); | ||
| 390 | + | ||
| 391 | + CV_Assert(dists.type() == CvType<DistanceType>::type()); | ||
| 392 | + CV_Assert(dists.isContinuous()); | ||
| 393 | + ::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols); | ||
| 394 | + | ||
| 395 | + FLANN_DISTANCE_CHECK | ||
| 396 | + | ||
| 397 | + nnIndex->knnSearch(m_queries,m_indices,m_dists,knn, searchParams); | ||
| 398 | +} | ||
| 399 | + | ||
| 400 | +template <typename Distance> | ||
| 401 | +int GenericIndex<Distance>::radiusSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams) | ||
| 402 | +{ | ||
| 403 | + ::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size()); | ||
| 404 | + ::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size()); | ||
| 405 | + ::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size()); | ||
| 406 | + | ||
| 407 | + FLANN_DISTANCE_CHECK | ||
| 408 | + | ||
| 409 | + return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,searchParams); | ||
| 410 | +} | ||
| 411 | + | ||
| 412 | +template <typename Distance> | ||
| 413 | +int GenericIndex<Distance>::radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams) | ||
| 414 | +{ | ||
| 415 | + CV_Assert(query.type() == CvType<ElementType>::type()); | ||
| 416 | + CV_Assert(query.isContinuous()); | ||
| 417 | + ::cvflann::Matrix<ElementType> m_query((ElementType*)query.ptr<ElementType>(0), query.rows, query.cols); | ||
| 418 | + | ||
| 419 | + CV_Assert(indices.type() == CV_32S); | ||
| 420 | + CV_Assert(indices.isContinuous()); | ||
| 421 | + ::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols); | ||
| 422 | + | ||
| 423 | + CV_Assert(dists.type() == CvType<DistanceType>::type()); | ||
| 424 | + CV_Assert(dists.isContinuous()); | ||
| 425 | + ::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols); | ||
| 426 | + | ||
| 427 | + FLANN_DISTANCE_CHECK | ||
| 428 | + | ||
| 429 | + return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,searchParams); | ||
| 430 | +} | ||
| 431 | + | ||
| 432 | +/** | ||
| 433 | + * @deprecated Use GenericIndex class instead | ||
| 434 | + */ | ||
| 435 | +template <typename T> | ||
| 436 | +class Index_ | ||
| 437 | +{ | ||
| 438 | +public: | ||
| 439 | + typedef typename L2<T>::ElementType ElementType; | ||
| 440 | + typedef typename L2<T>::ResultType DistanceType; | ||
| 441 | + | ||
| 442 | + CV_DEPRECATED Index_(const Mat& dataset, const ::cvflann::IndexParams& params) | ||
| 443 | + { | ||
| 444 | + printf("[WARNING] The cv::flann::Index_<T> class is deperecated, use cv::flann::GenericIndex<Distance> instead\n"); | ||
| 445 | + | ||
| 446 | + CV_Assert(dataset.type() == CvType<ElementType>::type()); | ||
| 447 | + CV_Assert(dataset.isContinuous()); | ||
| 448 | + ::cvflann::Matrix<ElementType> m_dataset((ElementType*)dataset.ptr<ElementType>(0), dataset.rows, dataset.cols); | ||
| 449 | + | ||
| 450 | + if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L2 ) { | ||
| 451 | + nnIndex_L1 = NULL; | ||
| 452 | + nnIndex_L2 = new ::cvflann::Index< L2<ElementType> >(m_dataset, params); | ||
| 453 | + } | ||
| 454 | + else if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L1 ) { | ||
| 455 | + nnIndex_L1 = new ::cvflann::Index< L1<ElementType> >(m_dataset, params); | ||
| 456 | + nnIndex_L2 = NULL; | ||
| 457 | + } | ||
| 458 | + else { | ||
| 459 | + printf("[ERROR] cv::flann::Index_<T> only provides backwards compatibility for the L1 and L2 distances. " | ||
| 460 | + "For other distance types you must use cv::flann::GenericIndex<Distance>\n"); | ||
| 461 | + CV_Assert(0); | ||
| 462 | + } | ||
| 463 | + if (nnIndex_L1) nnIndex_L1->buildIndex(); | ||
| 464 | + if (nnIndex_L2) nnIndex_L2->buildIndex(); | ||
| 465 | + } | ||
| 466 | + CV_DEPRECATED ~Index_() | ||
| 467 | + { | ||
| 468 | + if (nnIndex_L1) delete nnIndex_L1; | ||
| 469 | + if (nnIndex_L2) delete nnIndex_L2; | ||
| 470 | + } | ||
| 471 | + | ||
| 472 | + CV_DEPRECATED void knnSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& searchParams) | ||
| 473 | + { | ||
| 474 | + ::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size()); | ||
| 475 | + ::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size()); | ||
| 476 | + ::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size()); | ||
| 477 | + | ||
| 478 | + if (nnIndex_L1) nnIndex_L1->knnSearch(m_query,m_indices,m_dists,knn,searchParams); | ||
| 479 | + if (nnIndex_L2) nnIndex_L2->knnSearch(m_query,m_indices,m_dists,knn,searchParams); | ||
| 480 | + } | ||
| 481 | + CV_DEPRECATED void knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& searchParams) | ||
| 482 | + { | ||
| 483 | + CV_Assert(queries.type() == CvType<ElementType>::type()); | ||
| 484 | + CV_Assert(queries.isContinuous()); | ||
| 485 | + ::cvflann::Matrix<ElementType> m_queries((ElementType*)queries.ptr<ElementType>(0), queries.rows, queries.cols); | ||
| 486 | + | ||
| 487 | + CV_Assert(indices.type() == CV_32S); | ||
| 488 | + CV_Assert(indices.isContinuous()); | ||
| 489 | + ::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols); | ||
| 490 | + | ||
| 491 | + CV_Assert(dists.type() == CvType<DistanceType>::type()); | ||
| 492 | + CV_Assert(dists.isContinuous()); | ||
| 493 | + ::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols); | ||
| 494 | + | ||
| 495 | + if (nnIndex_L1) nnIndex_L1->knnSearch(m_queries,m_indices,m_dists,knn, searchParams); | ||
| 496 | + if (nnIndex_L2) nnIndex_L2->knnSearch(m_queries,m_indices,m_dists,knn, searchParams); | ||
| 497 | + } | ||
| 498 | + | ||
| 499 | + CV_DEPRECATED int radiusSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams) | ||
| 500 | + { | ||
| 501 | + ::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size()); | ||
| 502 | + ::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size()); | ||
| 503 | + ::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size()); | ||
| 504 | + | ||
| 505 | + if (nnIndex_L1) return nnIndex_L1->radiusSearch(m_query,m_indices,m_dists,radius,searchParams); | ||
| 506 | + if (nnIndex_L2) return nnIndex_L2->radiusSearch(m_query,m_indices,m_dists,radius,searchParams); | ||
| 507 | + } | ||
| 508 | + | ||
| 509 | + CV_DEPRECATED int radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams) | ||
| 510 | + { | ||
| 511 | + CV_Assert(query.type() == CvType<ElementType>::type()); | ||
| 512 | + CV_Assert(query.isContinuous()); | ||
| 513 | + ::cvflann::Matrix<ElementType> m_query((ElementType*)query.ptr<ElementType>(0), query.rows, query.cols); | ||
| 514 | + | ||
| 515 | + CV_Assert(indices.type() == CV_32S); | ||
| 516 | + CV_Assert(indices.isContinuous()); | ||
| 517 | + ::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols); | ||
| 518 | + | ||
| 519 | + CV_Assert(dists.type() == CvType<DistanceType>::type()); | ||
| 520 | + CV_Assert(dists.isContinuous()); | ||
| 521 | + ::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols); | ||
| 522 | + | ||
| 523 | + if (nnIndex_L1) return nnIndex_L1->radiusSearch(m_query,m_indices,m_dists,radius,searchParams); | ||
| 524 | + if (nnIndex_L2) return nnIndex_L2->radiusSearch(m_query,m_indices,m_dists,radius,searchParams); | ||
| 525 | + } | ||
| 526 | + | ||
| 527 | + CV_DEPRECATED void save(String filename) | ||
| 528 | + { | ||
| 529 | + if (nnIndex_L1) nnIndex_L1->save(filename); | ||
| 530 | + if (nnIndex_L2) nnIndex_L2->save(filename); | ||
| 531 | + } | ||
| 532 | + | ||
| 533 | + CV_DEPRECATED int veclen() const | ||
| 534 | + { | ||
| 535 | + if (nnIndex_L1) return nnIndex_L1->veclen(); | ||
| 536 | + if (nnIndex_L2) return nnIndex_L2->veclen(); | ||
| 537 | + } | ||
| 538 | + | ||
| 539 | + CV_DEPRECATED int size() const | ||
| 540 | + { | ||
| 541 | + if (nnIndex_L1) return nnIndex_L1->size(); | ||
| 542 | + if (nnIndex_L2) return nnIndex_L2->size(); | ||
| 543 | + } | ||
| 544 | + | ||
| 545 | + CV_DEPRECATED ::cvflann::IndexParams getParameters() | ||
| 546 | + { | ||
| 547 | + if (nnIndex_L1) return nnIndex_L1->getParameters(); | ||
| 548 | + if (nnIndex_L2) return nnIndex_L2->getParameters(); | ||
| 549 | + | ||
| 550 | + } | ||
| 551 | + | ||
| 552 | + CV_DEPRECATED const ::cvflann::IndexParams* getIndexParameters() | ||
| 553 | + { | ||
| 554 | + if (nnIndex_L1) return nnIndex_L1->getIndexParameters(); | ||
| 555 | + if (nnIndex_L2) return nnIndex_L2->getIndexParameters(); | ||
| 556 | + } | ||
| 557 | + | ||
| 558 | +private: | ||
| 559 | + // providing backwards compatibility for L2 and L1 distances (most common) | ||
| 560 | + ::cvflann::Index< L2<ElementType> >* nnIndex_L2; | ||
| 561 | + ::cvflann::Index< L1<ElementType> >* nnIndex_L1; | ||
| 562 | +}; | ||
| 563 | + | ||
| 564 | +//! @endcond | ||
| 565 | + | ||
| 566 | +/** @brief Clusters features using hierarchical k-means algorithm. | ||
| 567 | + | ||
| 568 | +@param features The points to be clustered. The matrix must have elements of type | ||
| 569 | +Distance::ElementType. | ||
| 570 | +@param centers The centers of the clusters obtained. The matrix must have type | ||
| 571 | +Distance::CentersType. The number of rows in this matrix represents the number of clusters desired, | ||
| 572 | +however, because of the way the cut in the hierarchical tree is chosen, the number of clusters | ||
| 573 | +computed will be the highest number of the form (branching-1)\*k+1 that's lower than the number of | ||
| 574 | +clusters desired, where branching is the tree's branching factor (see description of the | ||
| 575 | +KMeansIndexParams). | ||
| 576 | +@param params Parameters used in the construction of the hierarchical k-means tree. | ||
| 577 | +@param d Distance to be used for clustering. | ||
| 578 | + | ||
| 579 | +The method clusters the given feature vectors by constructing a hierarchical k-means tree and | ||
| 580 | +choosing a cut in the tree that minimizes the cluster's variance. It returns the number of clusters | ||
| 581 | +found. | ||
| 582 | + */ | ||
| 583 | +template <typename Distance> | ||
| 584 | +int hierarchicalClustering(const Mat& features, Mat& centers, const ::cvflann::KMeansIndexParams& params, | ||
| 585 | + Distance d = Distance()) | ||
| 586 | +{ | ||
| 587 | + typedef typename Distance::ElementType ElementType; | ||
| 588 | + typedef typename Distance::CentersType CentersType; | ||
| 589 | + | ||
| 590 | + CV_Assert(features.type() == CvType<ElementType>::type()); | ||
| 591 | + CV_Assert(features.isContinuous()); | ||
| 592 | + ::cvflann::Matrix<ElementType> m_features((ElementType*)features.ptr<ElementType>(0), features.rows, features.cols); | ||
| 593 | + | ||
| 594 | + CV_Assert(centers.type() == CvType<CentersType>::type()); | ||
| 595 | + CV_Assert(centers.isContinuous()); | ||
| 596 | + ::cvflann::Matrix<CentersType> m_centers((CentersType*)centers.ptr<CentersType>(0), centers.rows, centers.cols); | ||
| 597 | + | ||
| 598 | + return ::cvflann::hierarchicalClustering<Distance>(m_features, m_centers, params, d); | ||
| 599 | +} | ||
| 600 | + | ||
| 601 | +//! @cond IGNORED | ||
| 602 | + | ||
| 603 | +template <typename ELEM_TYPE, typename DIST_TYPE> | ||
| 604 | +CV_DEPRECATED int hierarchicalClustering(const Mat& features, Mat& centers, const ::cvflann::KMeansIndexParams& params) | ||
| 605 | +{ | ||
| 606 | + printf("[WARNING] cv::flann::hierarchicalClustering<ELEM_TYPE,DIST_TYPE> is deprecated, use " | ||
| 607 | + "cv::flann::hierarchicalClustering<Distance> instead\n"); | ||
| 608 | + | ||
| 609 | + if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L2 ) { | ||
| 610 | + return hierarchicalClustering< L2<ELEM_TYPE> >(features, centers, params); | ||
| 611 | + } | ||
| 612 | + else if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L1 ) { | ||
| 613 | + return hierarchicalClustering< L1<ELEM_TYPE> >(features, centers, params); | ||
| 614 | + } | ||
| 615 | + else { | ||
| 616 | + printf("[ERROR] cv::flann::hierarchicalClustering<ELEM_TYPE,DIST_TYPE> only provides backwards " | ||
| 617 | + "compatibility for the L1 and L2 distances. " | ||
| 618 | + "For other distance types you must use cv::flann::hierarchicalClustering<Distance>\n"); | ||
| 619 | + CV_Assert(0); | ||
| 620 | + } | ||
| 621 | +} | ||
| 622 | + | ||
| 623 | +//! @endcond | ||
| 624 | + | ||
| 625 | +//! @} flann | ||
| 626 | + | ||
| 627 | +} } // namespace cv::flann | ||
| 628 | + | ||
| 629 | +#endif |
| 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 | + * Redistribution and use in source and binary forms, with or without | ||
| 8 | + * modification, are permitted provided that the following conditions | ||
| 9 | + * are met: | ||
| 10 | + * | ||
| 11 | + * 1. Redistributions of source code must retain the above copyright | ||
| 12 | + * notice, this list of conditions and the following disclaimer. | ||
| 13 | + * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | + * notice, this list of conditions and the following disclaimer in the | ||
| 15 | + * documentation and/or other materials provided with the distribution. | ||
| 16 | + * | ||
| 17 | + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
| 18 | + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| 19 | + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| 20 | + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 21 | + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 22 | + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 23 | + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 24 | + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 25 | + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| 26 | + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 27 | + *************************************************************************/ | ||
| 28 | + | ||
| 29 | + | ||
| 30 | +#ifndef OPENCV_FLANN_ALL_INDICES_H_ | ||
| 31 | +#define OPENCV_FLANN_ALL_INDICES_H_ | ||
| 32 | + | ||
| 33 | +//! @cond IGNORED | ||
| 34 | + | ||
| 35 | +#include "general.h" | ||
| 36 | + | ||
| 37 | +#include "nn_index.h" | ||
| 38 | +#include "kdtree_index.h" | ||
| 39 | +#include "kdtree_single_index.h" | ||
| 40 | +#include "kmeans_index.h" | ||
| 41 | +#include "composite_index.h" | ||
| 42 | +#include "linear_index.h" | ||
| 43 | +#include "hierarchical_clustering_index.h" | ||
| 44 | +#include "lsh_index.h" | ||
| 45 | +#include "autotuned_index.h" | ||
| 46 | + | ||
| 47 | + | ||
| 48 | +namespace cvflann | ||
| 49 | +{ | ||
| 50 | + | ||
| 51 | +template<typename KDTreeCapability, typename VectorSpace, typename Distance> | ||
| 52 | +struct index_creator | ||
| 53 | +{ | ||
| 54 | + static NNIndex<Distance>* create(const Matrix<typename Distance::ElementType>& dataset, const IndexParams& params, const Distance& distance) | ||
| 55 | + { | ||
| 56 | + flann_algorithm_t index_type = get_param<flann_algorithm_t>(params, "algorithm"); | ||
| 57 | + | ||
| 58 | + NNIndex<Distance>* nnIndex; | ||
| 59 | + switch (index_type) { | ||
| 60 | + case FLANN_INDEX_LINEAR: | ||
| 61 | + nnIndex = new LinearIndex<Distance>(dataset, params, distance); | ||
| 62 | + break; | ||
| 63 | + case FLANN_INDEX_KDTREE_SINGLE: | ||
| 64 | + nnIndex = new KDTreeSingleIndex<Distance>(dataset, params, distance); | ||
| 65 | + break; | ||
| 66 | + case FLANN_INDEX_KDTREE: | ||
| 67 | + nnIndex = new KDTreeIndex<Distance>(dataset, params, distance); | ||
| 68 | + break; | ||
| 69 | + case FLANN_INDEX_KMEANS: | ||
| 70 | + nnIndex = new KMeansIndex<Distance>(dataset, params, distance); | ||
| 71 | + break; | ||
| 72 | + case FLANN_INDEX_COMPOSITE: | ||
| 73 | + nnIndex = new CompositeIndex<Distance>(dataset, params, distance); | ||
| 74 | + break; | ||
| 75 | + case FLANN_INDEX_AUTOTUNED: | ||
| 76 | + nnIndex = new AutotunedIndex<Distance>(dataset, params, distance); | ||
| 77 | + break; | ||
| 78 | + case FLANN_INDEX_HIERARCHICAL: | ||
| 79 | + nnIndex = new HierarchicalClusteringIndex<Distance>(dataset, params, distance); | ||
| 80 | + break; | ||
| 81 | + case FLANN_INDEX_LSH: | ||
| 82 | + nnIndex = new LshIndex<Distance>(dataset, params, distance); | ||
| 83 | + break; | ||
| 84 | + default: | ||
| 85 | + FLANN_THROW(cv::Error::StsBadArg, "Unknown index type"); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + return nnIndex; | ||
| 89 | + } | ||
| 90 | +}; | ||
| 91 | + | ||
| 92 | +template<typename VectorSpace, typename Distance> | ||
| 93 | +struct index_creator<False,VectorSpace,Distance> | ||
| 94 | +{ | ||
| 95 | + static NNIndex<Distance>* create(const Matrix<typename Distance::ElementType>& dataset, const IndexParams& params, const Distance& distance) | ||
| 96 | + { | ||
| 97 | + flann_algorithm_t index_type = get_param<flann_algorithm_t>(params, "algorithm"); | ||
| 98 | + | ||
| 99 | + NNIndex<Distance>* nnIndex; | ||
| 100 | + switch (index_type) { | ||
| 101 | + case FLANN_INDEX_LINEAR: | ||
| 102 | + nnIndex = new LinearIndex<Distance>(dataset, params, distance); | ||
| 103 | + break; | ||
| 104 | + case FLANN_INDEX_KMEANS: | ||
| 105 | + nnIndex = new KMeansIndex<Distance>(dataset, params, distance); | ||
| 106 | + break; | ||
| 107 | + case FLANN_INDEX_HIERARCHICAL: | ||
| 108 | + nnIndex = new HierarchicalClusteringIndex<Distance>(dataset, params, distance); | ||
| 109 | + break; | ||
| 110 | + case FLANN_INDEX_LSH: | ||
| 111 | + nnIndex = new LshIndex<Distance>(dataset, params, distance); | ||
| 112 | + break; | ||
| 113 | + default: | ||
| 114 | + FLANN_THROW(cv::Error::StsBadArg, "Unknown index type"); | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + return nnIndex; | ||
| 118 | + } | ||
| 119 | +}; | ||
| 120 | + | ||
| 121 | +template<typename Distance> | ||
| 122 | +struct index_creator<False,False,Distance> | ||
| 123 | +{ | ||
| 124 | + static NNIndex<Distance>* create(const Matrix<typename Distance::ElementType>& dataset, const IndexParams& params, const Distance& distance) | ||
| 125 | + { | ||
| 126 | + flann_algorithm_t index_type = get_param<flann_algorithm_t>(params, "algorithm"); | ||
| 127 | + | ||
| 128 | + NNIndex<Distance>* nnIndex; | ||
| 129 | + switch (index_type) { | ||
| 130 | + case FLANN_INDEX_LINEAR: | ||
| 131 | + nnIndex = new LinearIndex<Distance>(dataset, params, distance); | ||
| 132 | + break; | ||
| 133 | + case FLANN_INDEX_KMEANS: | ||
| 134 | + nnIndex = new KMeansIndex<Distance>(dataset, params, distance); | ||
| 135 | + break; | ||
| 136 | + case FLANN_INDEX_HIERARCHICAL: | ||
| 137 | + nnIndex = new HierarchicalClusteringIndex<Distance>(dataset, params, distance); | ||
| 138 | + break; | ||
| 139 | + case FLANN_INDEX_LSH: | ||
| 140 | + nnIndex = new LshIndex<Distance>(dataset, params, distance); | ||
| 141 | + break; | ||
| 142 | + default: | ||
| 143 | + FLANN_THROW(cv::Error::StsBadArg, "Unknown index type"); | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + return nnIndex; | ||
| 147 | + } | ||
| 148 | +}; | ||
| 149 | + | ||
| 150 | +template<typename Distance> | ||
| 151 | +NNIndex<Distance>* create_index_by_type(const Matrix<typename Distance::ElementType>& dataset, const IndexParams& params, const Distance& distance) | ||
| 152 | +{ | ||
| 153 | + return index_creator<typename Distance::is_kdtree_distance, | ||
| 154 | + typename Distance::is_vector_space_distance, | ||
| 155 | + Distance>::create(dataset, params,distance); | ||
| 156 | +} | ||
| 157 | + | ||
| 158 | +} | ||
| 159 | + | ||
| 160 | +//! @endcond | ||
| 161 | + | ||
| 162 | +#endif /* OPENCV_FLANN_ALL_INDICES_H_ */ |
| 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 | + | ||
| 31 | +#ifndef OPENCV_FLANN_ALLOCATOR_H_ | ||
| 32 | +#define OPENCV_FLANN_ALLOCATOR_H_ | ||
| 33 | + | ||
| 34 | +//! @cond IGNORED | ||
| 35 | + | ||
| 36 | +#include <stdlib.h> | ||
| 37 | +#include <stdio.h> | ||
| 38 | + | ||
| 39 | + | ||
| 40 | +namespace cvflann | ||
| 41 | +{ | ||
| 42 | + | ||
| 43 | +/** | ||
| 44 | + * Allocates (using C's malloc) a generic type T. | ||
| 45 | + * | ||
| 46 | + * Params: | ||
| 47 | + * count = number of instances to allocate. | ||
| 48 | + * Returns: pointer (of type T*) to memory buffer | ||
| 49 | + */ | ||
| 50 | +template <typename T> | ||
| 51 | +T* allocate(size_t count = 1) | ||
| 52 | +{ | ||
| 53 | + T* mem = (T*) ::malloc(sizeof(T)*count); | ||
| 54 | + return mem; | ||
| 55 | +} | ||
| 56 | + | ||
| 57 | + | ||
| 58 | +/** | ||
| 59 | + * Pooled storage allocator | ||
| 60 | + * | ||
| 61 | + * The following routines allow for the efficient allocation of storage in | ||
| 62 | + * small chunks from a specified pool. Rather than allowing each structure | ||
| 63 | + * to be freed individually, an entire pool of storage is freed at once. | ||
| 64 | + * This method has two advantages over just using malloc() and free(). First, | ||
| 65 | + * it is far more efficient for allocating small objects, as there is | ||
| 66 | + * no overhead for remembering all the information needed to free each | ||
| 67 | + * object or consolidating fragmented memory. Second, the decision about | ||
| 68 | + * how long to keep an object is made at the time of allocation, and there | ||
| 69 | + * is no need to track down all the objects to free them. | ||
| 70 | + * | ||
| 71 | + */ | ||
| 72 | + | ||
| 73 | +const size_t WORDSIZE=16; | ||
| 74 | +const size_t BLOCKSIZE=8192; | ||
| 75 | + | ||
| 76 | +class PooledAllocator | ||
| 77 | +{ | ||
| 78 | + /* We maintain memory alignment to word boundaries by requiring that all | ||
| 79 | + allocations be in multiples of the machine wordsize. */ | ||
| 80 | + /* Size of machine word in bytes. Must be power of 2. */ | ||
| 81 | + /* Minimum number of bytes requested at a time from the system. Must be multiple of WORDSIZE. */ | ||
| 82 | + | ||
| 83 | + | ||
| 84 | + int remaining; /* Number of bytes left in current block of storage. */ | ||
| 85 | + void* base; /* Pointer to base of current block of storage. */ | ||
| 86 | + void* loc; /* Current location in block to next allocate memory. */ | ||
| 87 | + int blocksize; | ||
| 88 | + | ||
| 89 | + | ||
| 90 | +public: | ||
| 91 | + int usedMemory; | ||
| 92 | + int wastedMemory; | ||
| 93 | + | ||
| 94 | + /** | ||
| 95 | + Default constructor. Initializes a new pool. | ||
| 96 | + */ | ||
| 97 | + PooledAllocator(int blockSize = BLOCKSIZE) | ||
| 98 | + { | ||
| 99 | + blocksize = blockSize; | ||
| 100 | + remaining = 0; | ||
| 101 | + base = NULL; | ||
| 102 | + loc = NULL; | ||
| 103 | + | ||
| 104 | + usedMemory = 0; | ||
| 105 | + wastedMemory = 0; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + /** | ||
| 109 | + * Destructor. Frees all the memory allocated in this pool. | ||
| 110 | + */ | ||
| 111 | + ~PooledAllocator() | ||
| 112 | + { | ||
| 113 | + void* prev; | ||
| 114 | + | ||
| 115 | + while (base != NULL) { | ||
| 116 | + prev = *((void**) base); /* Get pointer to prev block. */ | ||
| 117 | + ::free(base); | ||
| 118 | + base = prev; | ||
| 119 | + } | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + /** | ||
| 123 | + * Returns a pointer to a piece of new memory of the given size in bytes | ||
| 124 | + * allocated from the pool. | ||
| 125 | + */ | ||
| 126 | + void* allocateMemory(int size) | ||
| 127 | + { | ||
| 128 | + int blockSize; | ||
| 129 | + | ||
| 130 | + /* Round size up to a multiple of wordsize. The following expression | ||
| 131 | + only works for WORDSIZE that is a power of 2, by masking last bits of | ||
| 132 | + incremented size to zero. | ||
| 133 | + */ | ||
| 134 | + size = (size + (WORDSIZE - 1)) & ~(WORDSIZE - 1); | ||
| 135 | + | ||
| 136 | + /* Check whether a new block must be allocated. Note that the first word | ||
| 137 | + of a block is reserved for a pointer to the previous block. | ||
| 138 | + */ | ||
| 139 | + if (size > remaining) { | ||
| 140 | + | ||
| 141 | + wastedMemory += remaining; | ||
| 142 | + | ||
| 143 | + /* Allocate new storage. */ | ||
| 144 | + blockSize = (size + sizeof(void*) + (WORDSIZE-1) > BLOCKSIZE) ? | ||
| 145 | + size + sizeof(void*) + (WORDSIZE-1) : BLOCKSIZE; | ||
| 146 | + | ||
| 147 | + // use the standard C malloc to allocate memory | ||
| 148 | + void* m = ::malloc(blockSize); | ||
| 149 | + if (!m) { | ||
| 150 | + fprintf(stderr,"Failed to allocate memory.\n"); | ||
| 151 | + return NULL; | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + /* Fill first word of new block with pointer to previous block. */ | ||
| 155 | + ((void**) m)[0] = base; | ||
| 156 | + base = m; | ||
| 157 | + | ||
| 158 | + int shift = 0; | ||
| 159 | + //int shift = (WORDSIZE - ( (((size_t)m) + sizeof(void*)) & (WORDSIZE-1))) & (WORDSIZE-1); | ||
| 160 | + | ||
| 161 | + remaining = blockSize - sizeof(void*) - shift; | ||
| 162 | + loc = ((char*)m + sizeof(void*) + shift); | ||
| 163 | + } | ||
| 164 | + void* rloc = loc; | ||
| 165 | + loc = (char*)loc + size; | ||
| 166 | + remaining -= size; | ||
| 167 | + | ||
| 168 | + usedMemory += size; | ||
| 169 | + | ||
| 170 | + return rloc; | ||
| 171 | + } | ||
| 172 | + | ||
| 173 | + /** | ||
| 174 | + * Allocates (using this pool) a generic type T. | ||
| 175 | + * | ||
| 176 | + * Params: | ||
| 177 | + * count = number of instances to allocate. | ||
| 178 | + * Returns: pointer (of type T*) to memory buffer | ||
| 179 | + */ | ||
| 180 | + template <typename T> | ||
| 181 | + T* allocate(size_t count = 1) | ||
| 182 | + { | ||
| 183 | + T* mem = (T*) this->allocateMemory((int)(sizeof(T)*count)); | ||
| 184 | + return mem; | ||
| 185 | + } | ||
| 186 | + | ||
| 187 | +private: | ||
| 188 | + PooledAllocator(const PooledAllocator &); // copy disabled | ||
| 189 | + PooledAllocator& operator=(const PooledAllocator &); // assign disabled | ||
| 190 | +}; | ||
| 191 | + | ||
| 192 | +} | ||
| 193 | + | ||
| 194 | +//! @endcond | ||
| 195 | + | ||
| 196 | +#endif //OPENCV_FLANN_ALLOCATOR_H_ |
lite.ai.toolkit/include/opencv2/flann/any.h
0 → 100644
| 1 | +#ifndef OPENCV_FLANN_ANY_H_ | ||
| 2 | +#define OPENCV_FLANN_ANY_H_ | ||
| 3 | +/* | ||
| 4 | + * (C) Copyright Christopher Diggins 2005-2011 | ||
| 5 | + * (C) Copyright Pablo Aguilar 2005 | ||
| 6 | + * (C) Copyright Kevlin Henney 2001 | ||
| 7 | + * | ||
| 8 | + * Distributed under the Boost Software License, Version 1.0. (See | ||
| 9 | + * accompanying file LICENSE_1_0.txt or copy at | ||
| 10 | + * http://www.boost.org/LICENSE_1_0.txt | ||
| 11 | + * | ||
| 12 | + * Adapted for FLANN by Marius Muja | ||
| 13 | + */ | ||
| 14 | + | ||
| 15 | +//! @cond IGNORED | ||
| 16 | + | ||
| 17 | +#include "defines.h" | ||
| 18 | +#include <stdexcept> | ||
| 19 | +#include <ostream> | ||
| 20 | +#include <typeinfo> | ||
| 21 | + | ||
| 22 | +namespace cvflann | ||
| 23 | +{ | ||
| 24 | + | ||
| 25 | +namespace anyimpl | ||
| 26 | +{ | ||
| 27 | + | ||
| 28 | +struct bad_any_cast | ||
| 29 | +{ | ||
| 30 | +}; | ||
| 31 | + | ||
| 32 | +struct empty_any | ||
| 33 | +{ | ||
| 34 | +}; | ||
| 35 | + | ||
| 36 | +inline std::ostream& operator <<(std::ostream& out, const empty_any&) | ||
| 37 | +{ | ||
| 38 | + out << "[empty_any]"; | ||
| 39 | + return out; | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +struct base_any_policy | ||
| 43 | +{ | ||
| 44 | + virtual void static_delete(void** x) = 0; | ||
| 45 | + virtual void copy_from_value(void const* src, void** dest) = 0; | ||
| 46 | + virtual void clone(void* const* src, void** dest) = 0; | ||
| 47 | + virtual void move(void* const* src, void** dest) = 0; | ||
| 48 | + virtual void* get_value(void** src) = 0; | ||
| 49 | + virtual const void* get_value(void* const * src) = 0; | ||
| 50 | + virtual ::size_t get_size() = 0; | ||
| 51 | + virtual const std::type_info& type() = 0; | ||
| 52 | + virtual void print(std::ostream& out, void* const* src) = 0; | ||
| 53 | + virtual ~base_any_policy() {} | ||
| 54 | +}; | ||
| 55 | + | ||
| 56 | +template<typename T> | ||
| 57 | +struct typed_base_any_policy : base_any_policy | ||
| 58 | +{ | ||
| 59 | + virtual ::size_t get_size() CV_OVERRIDE { return sizeof(T); } | ||
| 60 | + virtual const std::type_info& type() CV_OVERRIDE { return typeid(T); } | ||
| 61 | + | ||
| 62 | +}; | ||
| 63 | + | ||
| 64 | +template<typename T> | ||
| 65 | +struct small_any_policy CV_FINAL : typed_base_any_policy<T> | ||
| 66 | +{ | ||
| 67 | + virtual void static_delete(void**) CV_OVERRIDE { } | ||
| 68 | + virtual void copy_from_value(void const* src, void** dest) CV_OVERRIDE | ||
| 69 | + { | ||
| 70 | + new (dest) T(* reinterpret_cast<T const*>(src)); | ||
| 71 | + } | ||
| 72 | + virtual void clone(void* const* src, void** dest) CV_OVERRIDE { *dest = *src; } | ||
| 73 | + virtual void move(void* const* src, void** dest) CV_OVERRIDE { *dest = *src; } | ||
| 74 | + virtual void* get_value(void** src) CV_OVERRIDE { return reinterpret_cast<void*>(src); } | ||
| 75 | + virtual const void* get_value(void* const * src) CV_OVERRIDE { return reinterpret_cast<const void*>(src); } | ||
| 76 | + virtual void print(std::ostream& out, void* const* src) CV_OVERRIDE { out << *reinterpret_cast<T const*>(src); } | ||
| 77 | +}; | ||
| 78 | + | ||
| 79 | +template<typename T> | ||
| 80 | +struct big_any_policy CV_FINAL : typed_base_any_policy<T> | ||
| 81 | +{ | ||
| 82 | + virtual void static_delete(void** x) CV_OVERRIDE | ||
| 83 | + { | ||
| 84 | + if (* x) delete (* reinterpret_cast<T**>(x)); | ||
| 85 | + *x = NULL; | ||
| 86 | + } | ||
| 87 | + virtual void copy_from_value(void const* src, void** dest) CV_OVERRIDE | ||
| 88 | + { | ||
| 89 | + *dest = new T(*reinterpret_cast<T const*>(src)); | ||
| 90 | + } | ||
| 91 | + virtual void clone(void* const* src, void** dest) CV_OVERRIDE | ||
| 92 | + { | ||
| 93 | + *dest = new T(**reinterpret_cast<T* const*>(src)); | ||
| 94 | + } | ||
| 95 | + virtual void move(void* const* src, void** dest) CV_OVERRIDE | ||
| 96 | + { | ||
| 97 | + (*reinterpret_cast<T**>(dest))->~T(); | ||
| 98 | + **reinterpret_cast<T**>(dest) = **reinterpret_cast<T* const*>(src); | ||
| 99 | + } | ||
| 100 | + virtual void* get_value(void** src) CV_OVERRIDE { return *src; } | ||
| 101 | + virtual const void* get_value(void* const * src) CV_OVERRIDE { return *src; } | ||
| 102 | + virtual void print(std::ostream& out, void* const* src) CV_OVERRIDE { out << *reinterpret_cast<T const*>(*src); } | ||
| 103 | +}; | ||
| 104 | + | ||
| 105 | +template<> inline void big_any_policy<flann_centers_init_t>::print(std::ostream& out, void* const* src) | ||
| 106 | +{ | ||
| 107 | + out << int(*reinterpret_cast<flann_centers_init_t const*>(*src)); | ||
| 108 | +} | ||
| 109 | + | ||
| 110 | +template<> inline void big_any_policy<flann_algorithm_t>::print(std::ostream& out, void* const* src) | ||
| 111 | +{ | ||
| 112 | + out << int(*reinterpret_cast<flann_algorithm_t const*>(*src)); | ||
| 113 | +} | ||
| 114 | + | ||
| 115 | +template<> inline void big_any_policy<cv::String>::print(std::ostream& out, void* const* src) | ||
| 116 | +{ | ||
| 117 | + out << (*reinterpret_cast<cv::String const*>(*src)).c_str(); | ||
| 118 | +} | ||
| 119 | + | ||
| 120 | +template<typename T> | ||
| 121 | +struct choose_policy | ||
| 122 | +{ | ||
| 123 | + typedef big_any_policy<T> type; | ||
| 124 | +}; | ||
| 125 | + | ||
| 126 | +template<typename T> | ||
| 127 | +struct choose_policy<T*> | ||
| 128 | +{ | ||
| 129 | + typedef small_any_policy<T*> type; | ||
| 130 | +}; | ||
| 131 | + | ||
| 132 | +struct any; | ||
| 133 | + | ||
| 134 | +/// Choosing the policy for an any type is illegal, but should never happen. | ||
| 135 | +/// This is designed to throw a compiler error. | ||
| 136 | +template<> | ||
| 137 | +struct choose_policy<any> | ||
| 138 | +{ | ||
| 139 | + typedef void type; | ||
| 140 | +}; | ||
| 141 | + | ||
| 142 | +/// Specializations for small types. | ||
| 143 | +#define SMALL_POLICY(TYPE) \ | ||
| 144 | + template<> \ | ||
| 145 | + struct choose_policy<TYPE> { typedef small_any_policy<TYPE> type; \ | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | +SMALL_POLICY(signed char); | ||
| 149 | +SMALL_POLICY(unsigned char); | ||
| 150 | +SMALL_POLICY(signed short); | ||
| 151 | +SMALL_POLICY(unsigned short); | ||
| 152 | +SMALL_POLICY(signed int); | ||
| 153 | +SMALL_POLICY(unsigned int); | ||
| 154 | +SMALL_POLICY(signed long); | ||
| 155 | +SMALL_POLICY(unsigned long); | ||
| 156 | +SMALL_POLICY(float); | ||
| 157 | +SMALL_POLICY(bool); | ||
| 158 | + | ||
| 159 | +#undef SMALL_POLICY | ||
| 160 | + | ||
| 161 | +template <typename T> | ||
| 162 | +class SinglePolicy | ||
| 163 | +{ | ||
| 164 | + SinglePolicy(); | ||
| 165 | + SinglePolicy(const SinglePolicy& other); | ||
| 166 | + SinglePolicy& operator=(const SinglePolicy& other); | ||
| 167 | + | ||
| 168 | +public: | ||
| 169 | + static base_any_policy* get_policy(); | ||
| 170 | + | ||
| 171 | +private: | ||
| 172 | + static typename choose_policy<T>::type policy; | ||
| 173 | +}; | ||
| 174 | + | ||
| 175 | +template <typename T> | ||
| 176 | +typename choose_policy<T>::type SinglePolicy<T>::policy; | ||
| 177 | + | ||
| 178 | +/// This function will return a different policy for each type. | ||
| 179 | +template <typename T> | ||
| 180 | +inline base_any_policy* SinglePolicy<T>::get_policy() { return &policy; } | ||
| 181 | + | ||
| 182 | +} // namespace anyimpl | ||
| 183 | + | ||
| 184 | +struct any | ||
| 185 | +{ | ||
| 186 | +private: | ||
| 187 | + // fields | ||
| 188 | + anyimpl::base_any_policy* policy; | ||
| 189 | + void* object; | ||
| 190 | + | ||
| 191 | +public: | ||
| 192 | + /// Initializing constructor. | ||
| 193 | + template <typename T> | ||
| 194 | + any(const T& x) | ||
| 195 | + : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL) | ||
| 196 | + { | ||
| 197 | + assign(x); | ||
| 198 | + } | ||
| 199 | + | ||
| 200 | + /// Empty constructor. | ||
| 201 | + any() | ||
| 202 | + : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL) | ||
| 203 | + { } | ||
| 204 | + | ||
| 205 | + /// Special initializing constructor for string literals. | ||
| 206 | + any(const char* x) | ||
| 207 | + : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL) | ||
| 208 | + { | ||
| 209 | + assign(x); | ||
| 210 | + } | ||
| 211 | + | ||
| 212 | + /// Copy constructor. | ||
| 213 | + any(const any& x) | ||
| 214 | + : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL) | ||
| 215 | + { | ||
| 216 | + assign(x); | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + /// Destructor. | ||
| 220 | + ~any() | ||
| 221 | + { | ||
| 222 | + policy->static_delete(&object); | ||
| 223 | + } | ||
| 224 | + | ||
| 225 | + /// Assignment function from another any. | ||
| 226 | + any& assign(const any& x) | ||
| 227 | + { | ||
| 228 | + reset(); | ||
| 229 | + policy = x.policy; | ||
| 230 | + policy->clone(&x.object, &object); | ||
| 231 | + return *this; | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + /// Assignment function. | ||
| 235 | + template <typename T> | ||
| 236 | + any& assign(const T& x) | ||
| 237 | + { | ||
| 238 | + reset(); | ||
| 239 | + policy = anyimpl::SinglePolicy<T>::get_policy(); | ||
| 240 | + policy->copy_from_value(&x, &object); | ||
| 241 | + return *this; | ||
| 242 | + } | ||
| 243 | + | ||
| 244 | + /// Assignment operator. | ||
| 245 | + template<typename T> | ||
| 246 | + any& operator=(const T& x) | ||
| 247 | + { | ||
| 248 | + return assign(x); | ||
| 249 | + } | ||
| 250 | + | ||
| 251 | + /// Assignment operator. Template-based version above doesn't work as expected. We need regular assignment operator here. | ||
| 252 | + any& operator=(const any& x) | ||
| 253 | + { | ||
| 254 | + return assign(x); | ||
| 255 | + } | ||
| 256 | + | ||
| 257 | + /// Assignment operator, specialed for literal strings. | ||
| 258 | + /// They have types like const char [6] which don't work as expected. | ||
| 259 | + any& operator=(const char* x) | ||
| 260 | + { | ||
| 261 | + return assign(x); | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + /// Utility functions | ||
| 265 | + any& swap(any& x) | ||
| 266 | + { | ||
| 267 | + std::swap(policy, x.policy); | ||
| 268 | + std::swap(object, x.object); | ||
| 269 | + return *this; | ||
| 270 | + } | ||
| 271 | + | ||
| 272 | + /// Cast operator. You can only cast to the original type. | ||
| 273 | + template<typename T> | ||
| 274 | + T& cast() | ||
| 275 | + { | ||
| 276 | + if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast(); | ||
| 277 | + T* r = reinterpret_cast<T*>(policy->get_value(&object)); | ||
| 278 | + return *r; | ||
| 279 | + } | ||
| 280 | + | ||
| 281 | + /// Cast operator. You can only cast to the original type. | ||
| 282 | + template<typename T> | ||
| 283 | + const T& cast() const | ||
| 284 | + { | ||
| 285 | + if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast(); | ||
| 286 | + const T* r = reinterpret_cast<const T*>(policy->get_value(&object)); | ||
| 287 | + return *r; | ||
| 288 | + } | ||
| 289 | + | ||
| 290 | + /// Returns true if the any contains no value. | ||
| 291 | + bool empty() const | ||
| 292 | + { | ||
| 293 | + return policy->type() == typeid(anyimpl::empty_any); | ||
| 294 | + } | ||
| 295 | + | ||
| 296 | + /// Frees any allocated memory, and sets the value to NULL. | ||
| 297 | + void reset() | ||
| 298 | + { | ||
| 299 | + policy->static_delete(&object); | ||
| 300 | + policy = anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy(); | ||
| 301 | + } | ||
| 302 | + | ||
| 303 | + /// Returns true if the two types are the same. | ||
| 304 | + bool compatible(const any& x) const | ||
| 305 | + { | ||
| 306 | + return policy->type() == x.policy->type(); | ||
| 307 | + } | ||
| 308 | + | ||
| 309 | + /// Returns if the type is compatible with the policy | ||
| 310 | + template<typename T> | ||
| 311 | + bool has_type() | ||
| 312 | + { | ||
| 313 | + return policy->type() == typeid(T); | ||
| 314 | + } | ||
| 315 | + | ||
| 316 | + const std::type_info& type() const | ||
| 317 | + { | ||
| 318 | + return policy->type(); | ||
| 319 | + } | ||
| 320 | + | ||
| 321 | + friend std::ostream& operator <<(std::ostream& out, const any& any_val); | ||
| 322 | +}; | ||
| 323 | + | ||
| 324 | +inline std::ostream& operator <<(std::ostream& out, const any& any_val) | ||
| 325 | +{ | ||
| 326 | + any_val.policy->print(out,&any_val.object); | ||
| 327 | + return out; | ||
| 328 | +} | ||
| 329 | + | ||
| 330 | +} | ||
| 331 | + | ||
| 332 | +//! @endcond | ||
| 333 | + | ||
| 334 | +#endif // OPENCV_FLANN_ANY_H_ |
| 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_AUTOTUNED_INDEX_H_ | ||
| 31 | +#define OPENCV_FLANN_AUTOTUNED_INDEX_H_ | ||
| 32 | + | ||
| 33 | +//! @cond IGNORED | ||
| 34 | + | ||
| 35 | +#include <sstream> | ||
| 36 | + | ||
| 37 | +#include "nn_index.h" | ||
| 38 | +#include "ground_truth.h" | ||
| 39 | +#include "index_testing.h" | ||
| 40 | +#include "sampling.h" | ||
| 41 | +#include "kdtree_index.h" | ||
| 42 | +#include "kdtree_single_index.h" | ||
| 43 | +#include "kmeans_index.h" | ||
| 44 | +#include "composite_index.h" | ||
| 45 | +#include "linear_index.h" | ||
| 46 | +#include "logger.h" | ||
| 47 | + | ||
| 48 | +namespace cvflann | ||
| 49 | +{ | ||
| 50 | + | ||
| 51 | +template<typename Distance> | ||
| 52 | +NNIndex<Distance>* create_index_by_type(const Matrix<typename Distance::ElementType>& dataset, const IndexParams& params, const Distance& distance); | ||
| 53 | + | ||
| 54 | + | ||
| 55 | +struct AutotunedIndexParams : public IndexParams | ||
| 56 | +{ | ||
| 57 | + AutotunedIndexParams(float target_precision = 0.8, float build_weight = 0.01, float memory_weight = 0, float sample_fraction = 0.1) | ||
| 58 | + { | ||
| 59 | + (*this)["algorithm"] = FLANN_INDEX_AUTOTUNED; | ||
| 60 | + // precision desired (used for autotuning, -1 otherwise) | ||
| 61 | + (*this)["target_precision"] = target_precision; | ||
| 62 | + // build tree time weighting factor | ||
| 63 | + (*this)["build_weight"] = build_weight; | ||
| 64 | + // index memory weighting factor | ||
| 65 | + (*this)["memory_weight"] = memory_weight; | ||
| 66 | + // what fraction of the dataset to use for autotuning | ||
| 67 | + (*this)["sample_fraction"] = sample_fraction; | ||
| 68 | + } | ||
| 69 | +}; | ||
| 70 | + | ||
| 71 | + | ||
| 72 | +template <typename Distance> | ||
| 73 | +class AutotunedIndex : public NNIndex<Distance> | ||
| 74 | +{ | ||
| 75 | +public: | ||
| 76 | + typedef typename Distance::ElementType ElementType; | ||
| 77 | + typedef typename Distance::ResultType DistanceType; | ||
| 78 | + | ||
| 79 | + AutotunedIndex(const Matrix<ElementType>& inputData, const IndexParams& params = AutotunedIndexParams(), Distance d = Distance()) : | ||
| 80 | + dataset_(inputData), distance_(d) | ||
| 81 | + { | ||
| 82 | + target_precision_ = get_param(params, "target_precision",0.8f); | ||
| 83 | + build_weight_ = get_param(params,"build_weight", 0.01f); | ||
| 84 | + memory_weight_ = get_param(params, "memory_weight", 0.0f); | ||
| 85 | + sample_fraction_ = get_param(params,"sample_fraction", 0.1f); | ||
| 86 | + bestIndex_ = NULL; | ||
| 87 | + speedup_ = 0; | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + AutotunedIndex(const AutotunedIndex&); | ||
| 91 | + AutotunedIndex& operator=(const AutotunedIndex&); | ||
| 92 | + | ||
| 93 | + virtual ~AutotunedIndex() | ||
| 94 | + { | ||
| 95 | + if (bestIndex_ != NULL) { | ||
| 96 | + delete bestIndex_; | ||
| 97 | + bestIndex_ = NULL; | ||
| 98 | + } | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + /** | ||
| 102 | + * Method responsible with building the index. | ||
| 103 | + */ | ||
| 104 | + virtual void buildIndex() CV_OVERRIDE | ||
| 105 | + { | ||
| 106 | + std::ostringstream stream; | ||
| 107 | + bestParams_ = estimateBuildParams(); | ||
| 108 | + print_params(bestParams_, stream); | ||
| 109 | + Logger::info("----------------------------------------------------\n"); | ||
| 110 | + Logger::info("Autotuned parameters:\n"); | ||
| 111 | + Logger::info("%s", stream.str().c_str()); | ||
| 112 | + Logger::info("----------------------------------------------------\n"); | ||
| 113 | + | ||
| 114 | + bestIndex_ = create_index_by_type(dataset_, bestParams_, distance_); | ||
| 115 | + bestIndex_->buildIndex(); | ||
| 116 | + speedup_ = estimateSearchParams(bestSearchParams_); | ||
| 117 | + stream.str(std::string()); | ||
| 118 | + print_params(bestSearchParams_, stream); | ||
| 119 | + Logger::info("----------------------------------------------------\n"); | ||
| 120 | + Logger::info("Search parameters:\n"); | ||
| 121 | + Logger::info("%s", stream.str().c_str()); | ||
| 122 | + Logger::info("----------------------------------------------------\n"); | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + /** | ||
| 126 | + * Saves the index to a stream | ||
| 127 | + */ | ||
| 128 | + virtual void saveIndex(FILE* stream) CV_OVERRIDE | ||
| 129 | + { | ||
| 130 | + save_value(stream, (int)bestIndex_->getType()); | ||
| 131 | + bestIndex_->saveIndex(stream); | ||
| 132 | + save_value(stream, get_param<int>(bestSearchParams_, "checks")); | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + /** | ||
| 136 | + * Loads the index from a stream | ||
| 137 | + */ | ||
| 138 | + virtual void loadIndex(FILE* stream) CV_OVERRIDE | ||
| 139 | + { | ||
| 140 | + int index_type; | ||
| 141 | + | ||
| 142 | + load_value(stream, index_type); | ||
| 143 | + IndexParams params; | ||
| 144 | + params["algorithm"] = (flann_algorithm_t)index_type; | ||
| 145 | + bestIndex_ = create_index_by_type<Distance>(dataset_, params, distance_); | ||
| 146 | + bestIndex_->loadIndex(stream); | ||
| 147 | + int checks; | ||
| 148 | + load_value(stream, checks); | ||
| 149 | + bestSearchParams_["checks"] = checks; | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + /** | ||
| 153 | + * Method that searches for nearest-neighbors | ||
| 154 | + */ | ||
| 155 | + virtual void findNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, const SearchParams& searchParams) CV_OVERRIDE | ||
| 156 | + { | ||
| 157 | + int checks = get_param<int>(searchParams,"checks",FLANN_CHECKS_AUTOTUNED); | ||
| 158 | + if (checks == FLANN_CHECKS_AUTOTUNED) { | ||
| 159 | + bestIndex_->findNeighbors(result, vec, bestSearchParams_); | ||
| 160 | + } | ||
| 161 | + else { | ||
| 162 | + bestIndex_->findNeighbors(result, vec, searchParams); | ||
| 163 | + } | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | + | ||
| 167 | + IndexParams getParameters() const CV_OVERRIDE | ||
| 168 | + { | ||
| 169 | + return bestIndex_->getParameters(); | ||
| 170 | + } | ||
| 171 | + | ||
| 172 | + SearchParams getSearchParameters() const | ||
| 173 | + { | ||
| 174 | + return bestSearchParams_; | ||
| 175 | + } | ||
| 176 | + | ||
| 177 | + float getSpeedup() const | ||
| 178 | + { | ||
| 179 | + return speedup_; | ||
| 180 | + } | ||
| 181 | + | ||
| 182 | + | ||
| 183 | + /** | ||
| 184 | + * Number of features in this index. | ||
| 185 | + */ | ||
| 186 | + virtual size_t size() const CV_OVERRIDE | ||
| 187 | + { | ||
| 188 | + return bestIndex_->size(); | ||
| 189 | + } | ||
| 190 | + | ||
| 191 | + /** | ||
| 192 | + * The length of each vector in this index. | ||
| 193 | + */ | ||
| 194 | + virtual size_t veclen() const CV_OVERRIDE | ||
| 195 | + { | ||
| 196 | + return bestIndex_->veclen(); | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + /** | ||
| 200 | + * The amount of memory (in bytes) this index uses. | ||
| 201 | + */ | ||
| 202 | + virtual int usedMemory() const CV_OVERRIDE | ||
| 203 | + { | ||
| 204 | + return bestIndex_->usedMemory(); | ||
| 205 | + } | ||
| 206 | + | ||
| 207 | + /** | ||
| 208 | + * Algorithm name | ||
| 209 | + */ | ||
| 210 | + virtual flann_algorithm_t getType() const CV_OVERRIDE | ||
| 211 | + { | ||
| 212 | + return FLANN_INDEX_AUTOTUNED; | ||
| 213 | + } | ||
| 214 | + | ||
| 215 | +private: | ||
| 216 | + | ||
| 217 | + struct CostData | ||
| 218 | + { | ||
| 219 | + float searchTimeCost; | ||
| 220 | + float buildTimeCost; | ||
| 221 | + float memoryCost; | ||
| 222 | + float totalCost; | ||
| 223 | + IndexParams params; | ||
| 224 | + }; | ||
| 225 | + | ||
| 226 | + void evaluate_kmeans(CostData& cost) | ||
| 227 | + { | ||
| 228 | + StartStopTimer t; | ||
| 229 | + int checks; | ||
| 230 | + const int nn = 1; | ||
| 231 | + | ||
| 232 | + Logger::info("KMeansTree using params: max_iterations=%d, branching=%d\n", | ||
| 233 | + get_param<int>(cost.params,"iterations"), | ||
| 234 | + get_param<int>(cost.params,"branching")); | ||
| 235 | + KMeansIndex<Distance> kmeans(sampledDataset_, cost.params, distance_); | ||
| 236 | + // measure index build time | ||
| 237 | + t.start(); | ||
| 238 | + kmeans.buildIndex(); | ||
| 239 | + t.stop(); | ||
| 240 | + float buildTime = (float)t.value; | ||
| 241 | + | ||
| 242 | + // measure search time | ||
| 243 | + float searchTime = test_index_precision(kmeans, sampledDataset_, testDataset_, gt_matches_, target_precision_, checks, distance_, nn); | ||
| 244 | + | ||
| 245 | + float datasetMemory = float(sampledDataset_.rows * sampledDataset_.cols * sizeof(float)); | ||
| 246 | + cost.memoryCost = (kmeans.usedMemory() + datasetMemory) / datasetMemory; | ||
| 247 | + cost.searchTimeCost = searchTime; | ||
| 248 | + cost.buildTimeCost = buildTime; | ||
| 249 | + Logger::info("KMeansTree buildTime=%g, searchTime=%g, build_weight=%g\n", buildTime, searchTime, build_weight_); | ||
| 250 | + } | ||
| 251 | + | ||
| 252 | + | ||
| 253 | + void evaluate_kdtree(CostData& cost) | ||
| 254 | + { | ||
| 255 | + StartStopTimer t; | ||
| 256 | + int checks; | ||
| 257 | + const int nn = 1; | ||
| 258 | + | ||
| 259 | + Logger::info("KDTree using params: trees=%d\n", get_param<int>(cost.params,"trees")); | ||
| 260 | + KDTreeIndex<Distance> kdtree(sampledDataset_, cost.params, distance_); | ||
| 261 | + | ||
| 262 | + t.start(); | ||
| 263 | + kdtree.buildIndex(); | ||
| 264 | + t.stop(); | ||
| 265 | + float buildTime = (float)t.value; | ||
| 266 | + | ||
| 267 | + //measure search time | ||
| 268 | + float searchTime = test_index_precision(kdtree, sampledDataset_, testDataset_, gt_matches_, target_precision_, checks, distance_, nn); | ||
| 269 | + | ||
| 270 | + float datasetMemory = float(sampledDataset_.rows * sampledDataset_.cols * sizeof(float)); | ||
| 271 | + cost.memoryCost = (kdtree.usedMemory() + datasetMemory) / datasetMemory; | ||
| 272 | + cost.searchTimeCost = searchTime; | ||
| 273 | + cost.buildTimeCost = buildTime; | ||
| 274 | + Logger::info("KDTree buildTime=%g, searchTime=%g\n", buildTime, searchTime); | ||
| 275 | + } | ||
| 276 | + | ||
| 277 | + | ||
| 278 | + // struct KMeansSimpleDownhillFunctor { | ||
| 279 | + // | ||
| 280 | + // Autotune& autotuner; | ||
| 281 | + // KMeansSimpleDownhillFunctor(Autotune& autotuner_) : autotuner(autotuner_) {} | ||
| 282 | + // | ||
| 283 | + // float operator()(int* params) { | ||
| 284 | + // | ||
| 285 | + // float maxFloat = numeric_limits<float>::max(); | ||
| 286 | + // | ||
| 287 | + // if (params[0]<2) return maxFloat; | ||
| 288 | + // if (params[1]<0) return maxFloat; | ||
| 289 | + // | ||
| 290 | + // CostData c; | ||
| 291 | + // c.params["algorithm"] = KMEANS; | ||
| 292 | + // c.params["centers-init"] = CENTERS_RANDOM; | ||
| 293 | + // c.params["branching"] = params[0]; | ||
| 294 | + // c.params["max-iterations"] = params[1]; | ||
| 295 | + // | ||
| 296 | + // autotuner.evaluate_kmeans(c); | ||
| 297 | + // | ||
| 298 | + // return c.timeCost; | ||
| 299 | + // | ||
| 300 | + // } | ||
| 301 | + // }; | ||
| 302 | + // | ||
| 303 | + // struct KDTreeSimpleDownhillFunctor { | ||
| 304 | + // | ||
| 305 | + // Autotune& autotuner; | ||
| 306 | + // KDTreeSimpleDownhillFunctor(Autotune& autotuner_) : autotuner(autotuner_) {} | ||
| 307 | + // | ||
| 308 | + // float operator()(int* params) { | ||
| 309 | + // float maxFloat = numeric_limits<float>::max(); | ||
| 310 | + // | ||
| 311 | + // if (params[0]<1) return maxFloat; | ||
| 312 | + // | ||
| 313 | + // CostData c; | ||
| 314 | + // c.params["algorithm"] = KDTREE; | ||
| 315 | + // c.params["trees"] = params[0]; | ||
| 316 | + // | ||
| 317 | + // autotuner.evaluate_kdtree(c); | ||
| 318 | + // | ||
| 319 | + // return c.timeCost; | ||
| 320 | + // | ||
| 321 | + // } | ||
| 322 | + // }; | ||
| 323 | + | ||
| 324 | + | ||
| 325 | + | ||
| 326 | + void optimizeKMeans(std::vector<CostData>& costs) | ||
| 327 | + { | ||
| 328 | + Logger::info("KMEANS, Step 1: Exploring parameter space\n"); | ||
| 329 | + | ||
| 330 | + // explore kmeans parameters space using combinations of the parameters below | ||
| 331 | + int maxIterations[] = { 1, 5, 10, 15 }; | ||
| 332 | + int branchingFactors[] = { 16, 32, 64, 128, 256 }; | ||
| 333 | + | ||
| 334 | + int kmeansParamSpaceSize = FLANN_ARRAY_LEN(maxIterations) * FLANN_ARRAY_LEN(branchingFactors); | ||
| 335 | + costs.reserve(costs.size() + kmeansParamSpaceSize); | ||
| 336 | + | ||
| 337 | + // evaluate kmeans for all parameter combinations | ||
| 338 | + for (size_t i = 0; i < FLANN_ARRAY_LEN(maxIterations); ++i) { | ||
| 339 | + for (size_t j = 0; j < FLANN_ARRAY_LEN(branchingFactors); ++j) { | ||
| 340 | + CostData cost; | ||
| 341 | + cost.params["algorithm"] = FLANN_INDEX_KMEANS; | ||
| 342 | + cost.params["centers_init"] = FLANN_CENTERS_RANDOM; | ||
| 343 | + cost.params["iterations"] = maxIterations[i]; | ||
| 344 | + cost.params["branching"] = branchingFactors[j]; | ||
| 345 | + | ||
| 346 | + evaluate_kmeans(cost); | ||
| 347 | + costs.push_back(cost); | ||
| 348 | + } | ||
| 349 | + } | ||
| 350 | + | ||
| 351 | + // Logger::info("KMEANS, Step 2: simplex-downhill optimization\n"); | ||
| 352 | + // | ||
| 353 | + // const int n = 2; | ||
| 354 | + // // choose initial simplex points as the best parameters so far | ||
| 355 | + // int kmeansNMPoints[n*(n+1)]; | ||
| 356 | + // float kmeansVals[n+1]; | ||
| 357 | + // for (int i=0;i<n+1;++i) { | ||
| 358 | + // kmeansNMPoints[i*n] = (int)kmeansCosts[i].params["branching"]; | ||
| 359 | + // kmeansNMPoints[i*n+1] = (int)kmeansCosts[i].params["max-iterations"]; | ||
| 360 | + // kmeansVals[i] = kmeansCosts[i].timeCost; | ||
| 361 | + // } | ||
| 362 | + // KMeansSimpleDownhillFunctor kmeans_cost_func(*this); | ||
| 363 | + // // run optimization | ||
| 364 | + // optimizeSimplexDownhill(kmeansNMPoints,n,kmeans_cost_func,kmeansVals); | ||
| 365 | + // // store results | ||
| 366 | + // for (int i=0;i<n+1;++i) { | ||
| 367 | + // kmeansCosts[i].params["branching"] = kmeansNMPoints[i*2]; | ||
| 368 | + // kmeansCosts[i].params["max-iterations"] = kmeansNMPoints[i*2+1]; | ||
| 369 | + // kmeansCosts[i].timeCost = kmeansVals[i]; | ||
| 370 | + // } | ||
| 371 | + } | ||
| 372 | + | ||
| 373 | + | ||
| 374 | + void optimizeKDTree(std::vector<CostData>& costs) | ||
| 375 | + { | ||
| 376 | + Logger::info("KD-TREE, Step 1: Exploring parameter space\n"); | ||
| 377 | + | ||
| 378 | + // explore kd-tree parameters space using the parameters below | ||
| 379 | + int testTrees[] = { 1, 4, 8, 16, 32 }; | ||
| 380 | + | ||
| 381 | + // evaluate kdtree for all parameter combinations | ||
| 382 | + for (size_t i = 0; i < FLANN_ARRAY_LEN(testTrees); ++i) { | ||
| 383 | + CostData cost; | ||
| 384 | + cost.params["algorithm"] = FLANN_INDEX_KDTREE; | ||
| 385 | + cost.params["trees"] = testTrees[i]; | ||
| 386 | + | ||
| 387 | + evaluate_kdtree(cost); | ||
| 388 | + costs.push_back(cost); | ||
| 389 | + } | ||
| 390 | + | ||
| 391 | + // Logger::info("KD-TREE, Step 2: simplex-downhill optimization\n"); | ||
| 392 | + // | ||
| 393 | + // const int n = 1; | ||
| 394 | + // // choose initial simplex points as the best parameters so far | ||
| 395 | + // int kdtreeNMPoints[n*(n+1)]; | ||
| 396 | + // float kdtreeVals[n+1]; | ||
| 397 | + // for (int i=0;i<n+1;++i) { | ||
| 398 | + // kdtreeNMPoints[i] = (int)kdtreeCosts[i].params["trees"]; | ||
| 399 | + // kdtreeVals[i] = kdtreeCosts[i].timeCost; | ||
| 400 | + // } | ||
| 401 | + // KDTreeSimpleDownhillFunctor kdtree_cost_func(*this); | ||
| 402 | + // // run optimization | ||
| 403 | + // optimizeSimplexDownhill(kdtreeNMPoints,n,kdtree_cost_func,kdtreeVals); | ||
| 404 | + // // store results | ||
| 405 | + // for (int i=0;i<n+1;++i) { | ||
| 406 | + // kdtreeCosts[i].params["trees"] = kdtreeNMPoints[i]; | ||
| 407 | + // kdtreeCosts[i].timeCost = kdtreeVals[i]; | ||
| 408 | + // } | ||
| 409 | + } | ||
| 410 | + | ||
| 411 | + /** | ||
| 412 | + * Chooses the best nearest-neighbor algorithm and estimates the optimal | ||
| 413 | + * parameters to use when building the index (for a given precision). | ||
| 414 | + * Returns a dictionary with the optimal parameters. | ||
| 415 | + */ | ||
| 416 | + IndexParams estimateBuildParams() | ||
| 417 | + { | ||
| 418 | + std::vector<CostData> costs; | ||
| 419 | + | ||
| 420 | + int sampleSize = int(sample_fraction_ * dataset_.rows); | ||
| 421 | + int testSampleSize = std::min(sampleSize / 10, 1000); | ||
| 422 | + | ||
| 423 | + Logger::info("Entering autotuning, dataset size: %d, sampleSize: %d, testSampleSize: %d, target precision: %g\n", dataset_.rows, sampleSize, testSampleSize, target_precision_); | ||
| 424 | + | ||
| 425 | + // For a very small dataset, it makes no sense to build any fancy index, just | ||
| 426 | + // use linear search | ||
| 427 | + if (testSampleSize < 10) { | ||
| 428 | + Logger::info("Choosing linear, dataset too small\n"); | ||
| 429 | + return LinearIndexParams(); | ||
| 430 | + } | ||
| 431 | + | ||
| 432 | + // We use a fraction of the original dataset to speedup the autotune algorithm | ||
| 433 | + sampledDataset_ = random_sample(dataset_, sampleSize); | ||
| 434 | + // We use a cross-validation approach, first we sample a testset from the dataset | ||
| 435 | + testDataset_ = random_sample(sampledDataset_, testSampleSize, true); | ||
| 436 | + | ||
| 437 | + // We compute the ground truth using linear search | ||
| 438 | + Logger::info("Computing ground truth... \n"); | ||
| 439 | + gt_matches_ = Matrix<int>(new int[testDataset_.rows], testDataset_.rows, 1); | ||
| 440 | + StartStopTimer t; | ||
| 441 | + t.start(); | ||
| 442 | + compute_ground_truth<Distance>(sampledDataset_, testDataset_, gt_matches_, 0, distance_); | ||
| 443 | + t.stop(); | ||
| 444 | + | ||
| 445 | + CostData linear_cost; | ||
| 446 | + linear_cost.searchTimeCost = (float)t.value; | ||
| 447 | + linear_cost.buildTimeCost = 0; | ||
| 448 | + linear_cost.memoryCost = 0; | ||
| 449 | + linear_cost.params["algorithm"] = FLANN_INDEX_LINEAR; | ||
| 450 | + | ||
| 451 | + costs.push_back(linear_cost); | ||
| 452 | + | ||
| 453 | + // Start parameter autotune process | ||
| 454 | + Logger::info("Autotuning parameters...\n"); | ||
| 455 | + | ||
| 456 | + optimizeKMeans(costs); | ||
| 457 | + optimizeKDTree(costs); | ||
| 458 | + | ||
| 459 | + float bestTimeCost = costs[0].searchTimeCost; | ||
| 460 | + for (size_t i = 0; i < costs.size(); ++i) { | ||
| 461 | + float timeCost = costs[i].buildTimeCost * build_weight_ + costs[i].searchTimeCost; | ||
| 462 | + if (timeCost < bestTimeCost) { | ||
| 463 | + bestTimeCost = timeCost; | ||
| 464 | + } | ||
| 465 | + } | ||
| 466 | + | ||
| 467 | + float bestCost = costs[0].searchTimeCost / bestTimeCost; | ||
| 468 | + IndexParams bestParams = costs[0].params; | ||
| 469 | + if (bestTimeCost > 0) { | ||
| 470 | + for (size_t i = 0; i < costs.size(); ++i) { | ||
| 471 | + float crtCost = (costs[i].buildTimeCost * build_weight_ + costs[i].searchTimeCost) / bestTimeCost + | ||
| 472 | + memory_weight_ * costs[i].memoryCost; | ||
| 473 | + if (crtCost < bestCost) { | ||
| 474 | + bestCost = crtCost; | ||
| 475 | + bestParams = costs[i].params; | ||
| 476 | + } | ||
| 477 | + } | ||
| 478 | + } | ||
| 479 | + | ||
| 480 | + delete[] gt_matches_.data; | ||
| 481 | + delete[] testDataset_.data; | ||
| 482 | + delete[] sampledDataset_.data; | ||
| 483 | + | ||
| 484 | + return bestParams; | ||
| 485 | + } | ||
| 486 | + | ||
| 487 | + | ||
| 488 | + | ||
| 489 | + /** | ||
| 490 | + * Estimates the search time parameters needed to get the desired precision. | ||
| 491 | + * Precondition: the index is built | ||
| 492 | + * Postcondition: the searchParams will have the optimum params set, also the speedup obtained over linear search. | ||
| 493 | + */ | ||
| 494 | + float estimateSearchParams(SearchParams& searchParams) | ||
| 495 | + { | ||
| 496 | + const int nn = 1; | ||
| 497 | + const size_t SAMPLE_COUNT = 1000; | ||
| 498 | + | ||
| 499 | + CV_Assert(bestIndex_ != NULL && "Requires a valid index"); // must have a valid index | ||
| 500 | + | ||
| 501 | + float speedup = 0; | ||
| 502 | + | ||
| 503 | + int samples = (int)std::min(dataset_.rows / 10, SAMPLE_COUNT); | ||
| 504 | + if (samples > 0) { | ||
| 505 | + Matrix<ElementType> testDataset = random_sample(dataset_, samples); | ||
| 506 | + | ||
| 507 | + Logger::info("Computing ground truth\n"); | ||
| 508 | + | ||
| 509 | + // we need to compute the ground truth first | ||
| 510 | + Matrix<int> gt_matches(new int[testDataset.rows], testDataset.rows, 1); | ||
| 511 | + StartStopTimer t; | ||
| 512 | + t.start(); | ||
| 513 | + compute_ground_truth<Distance>(dataset_, testDataset, gt_matches, 1, distance_); | ||
| 514 | + t.stop(); | ||
| 515 | + float linear = (float)t.value; | ||
| 516 | + | ||
| 517 | + int checks; | ||
| 518 | + Logger::info("Estimating number of checks\n"); | ||
| 519 | + | ||
| 520 | + float searchTime; | ||
| 521 | + float cb_index; | ||
| 522 | + if (bestIndex_->getType() == FLANN_INDEX_KMEANS) { | ||
| 523 | + Logger::info("KMeans algorithm, estimating cluster border factor\n"); | ||
| 524 | + KMeansIndex<Distance>* kmeans = (KMeansIndex<Distance>*)bestIndex_; | ||
| 525 | + float bestSearchTime = -1; | ||
| 526 | + float best_cb_index = -1; | ||
| 527 | + int best_checks = -1; | ||
| 528 | + for (cb_index = 0; cb_index < 1.1f; cb_index += 0.2f) { | ||
| 529 | + kmeans->set_cb_index(cb_index); | ||
| 530 | + searchTime = test_index_precision(*kmeans, dataset_, testDataset, gt_matches, target_precision_, checks, distance_, nn, 1); | ||
| 531 | + if ((searchTime < bestSearchTime) || (bestSearchTime == -1)) { | ||
| 532 | + bestSearchTime = searchTime; | ||
| 533 | + best_cb_index = cb_index; | ||
| 534 | + best_checks = checks; | ||
| 535 | + } | ||
| 536 | + } | ||
| 537 | + searchTime = bestSearchTime; | ||
| 538 | + cb_index = best_cb_index; | ||
| 539 | + checks = best_checks; | ||
| 540 | + | ||
| 541 | + kmeans->set_cb_index(best_cb_index); | ||
| 542 | + Logger::info("Optimum cb_index: %g\n", cb_index); | ||
| 543 | + bestParams_["cb_index"] = cb_index; | ||
| 544 | + } | ||
| 545 | + else { | ||
| 546 | + searchTime = test_index_precision(*bestIndex_, dataset_, testDataset, gt_matches, target_precision_, checks, distance_, nn, 1); | ||
| 547 | + } | ||
| 548 | + | ||
| 549 | + Logger::info("Required number of checks: %d \n", checks); | ||
| 550 | + searchParams["checks"] = checks; | ||
| 551 | + | ||
| 552 | + speedup = linear / searchTime; | ||
| 553 | + | ||
| 554 | + delete[] gt_matches.data; | ||
| 555 | + delete[] testDataset.data; | ||
| 556 | + } | ||
| 557 | + | ||
| 558 | + return speedup; | ||
| 559 | + } | ||
| 560 | + | ||
| 561 | +private: | ||
| 562 | + NNIndex<Distance>* bestIndex_; | ||
| 563 | + | ||
| 564 | + IndexParams bestParams_; | ||
| 565 | + SearchParams bestSearchParams_; | ||
| 566 | + | ||
| 567 | + Matrix<ElementType> sampledDataset_; | ||
| 568 | + Matrix<ElementType> testDataset_; | ||
| 569 | + Matrix<int> gt_matches_; | ||
| 570 | + | ||
| 571 | + float speedup_; | ||
| 572 | + | ||
| 573 | + /** | ||
| 574 | + * The dataset used by this index | ||
| 575 | + */ | ||
| 576 | + const Matrix<ElementType> dataset_; | ||
| 577 | + | ||
| 578 | + /** | ||
| 579 | + * Index parameters | ||
| 580 | + */ | ||
| 581 | + float target_precision_; | ||
| 582 | + float build_weight_; | ||
| 583 | + float memory_weight_; | ||
| 584 | + float sample_fraction_; | ||
| 585 | + | ||
| 586 | + Distance distance_; | ||
| 587 | + | ||
| 588 | + | ||
| 589 | +}; | ||
| 590 | +} | ||
| 591 | + | ||
| 592 | +//! @endcond | ||
| 593 | + | ||
| 594 | +#endif /* OPENCV_FLANN_AUTOTUNED_INDEX_H_ */ |
| 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 | + | ||
| 31 | +#ifndef OPENCV_FLANN_COMPOSITE_INDEX_H_ | ||
| 32 | +#define OPENCV_FLANN_COMPOSITE_INDEX_H_ | ||
| 33 | + | ||
| 34 | +//! @cond IGNORED | ||
| 35 | + | ||
| 36 | +#include "nn_index.h" | ||
| 37 | +#include "kdtree_index.h" | ||
| 38 | +#include "kmeans_index.h" | ||
| 39 | + | ||
| 40 | +namespace cvflann | ||
| 41 | +{ | ||
| 42 | + | ||
| 43 | +/** | ||
| 44 | + * Index parameters for the CompositeIndex. | ||
| 45 | + */ | ||
| 46 | +struct CompositeIndexParams : public IndexParams | ||
| 47 | +{ | ||
| 48 | + CompositeIndexParams(int trees = 4, int branching = 32, int iterations = 11, | ||
| 49 | + flann_centers_init_t centers_init = FLANN_CENTERS_RANDOM, float cb_index = 0.2 ) | ||
| 50 | + { | ||
| 51 | + (*this)["algorithm"] = FLANN_INDEX_KMEANS; | ||
| 52 | + // number of randomized trees to use (for kdtree) | ||
| 53 | + (*this)["trees"] = trees; | ||
| 54 | + // branching factor | ||
| 55 | + (*this)["branching"] = branching; | ||
| 56 | + // max iterations to perform in one kmeans clustering (kmeans tree) | ||
| 57 | + (*this)["iterations"] = iterations; | ||
| 58 | + // algorithm used for picking the initial cluster centers for kmeans tree | ||
| 59 | + (*this)["centers_init"] = centers_init; | ||
| 60 | + // cluster boundary index. Used when searching the kmeans tree | ||
| 61 | + (*this)["cb_index"] = cb_index; | ||
| 62 | + } | ||
| 63 | +}; | ||
| 64 | + | ||
| 65 | + | ||
| 66 | +/** | ||
| 67 | + * This index builds a kd-tree index and a k-means index and performs nearest | ||
| 68 | + * neighbour search both indexes. This gives a slight boost in search performance | ||
| 69 | + * as some of the neighbours that are missed by one index are found by the other. | ||
| 70 | + */ | ||
| 71 | +template <typename Distance> | ||
| 72 | +class CompositeIndex : public NNIndex<Distance> | ||
| 73 | +{ | ||
| 74 | +public: | ||
| 75 | + typedef typename Distance::ElementType ElementType; | ||
| 76 | + typedef typename Distance::ResultType DistanceType; | ||
| 77 | + | ||
| 78 | + /** | ||
| 79 | + * Index constructor | ||
| 80 | + * @param inputData dataset containing the points to index | ||
| 81 | + * @param params Index parameters | ||
| 82 | + * @param d Distance functor | ||
| 83 | + * @return | ||
| 84 | + */ | ||
| 85 | + CompositeIndex(const Matrix<ElementType>& inputData, const IndexParams& params = CompositeIndexParams(), | ||
| 86 | + Distance d = Distance()) : index_params_(params) | ||
| 87 | + { | ||
| 88 | + kdtree_index_ = new KDTreeIndex<Distance>(inputData, params, d); | ||
| 89 | + kmeans_index_ = new KMeansIndex<Distance>(inputData, params, d); | ||
| 90 | + | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + CompositeIndex(const CompositeIndex&); | ||
| 94 | + CompositeIndex& operator=(const CompositeIndex&); | ||
| 95 | + | ||
| 96 | + virtual ~CompositeIndex() | ||
| 97 | + { | ||
| 98 | + delete kdtree_index_; | ||
| 99 | + delete kmeans_index_; | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + /** | ||
| 103 | + * @return The index type | ||
| 104 | + */ | ||
| 105 | + flann_algorithm_t getType() const CV_OVERRIDE | ||
| 106 | + { | ||
| 107 | + return FLANN_INDEX_COMPOSITE; | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + /** | ||
| 111 | + * @return Size of the index | ||
| 112 | + */ | ||
| 113 | + size_t size() const CV_OVERRIDE | ||
| 114 | + { | ||
| 115 | + return kdtree_index_->size(); | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + /** | ||
| 119 | + * \returns The dimensionality of the features in this index. | ||
| 120 | + */ | ||
| 121 | + size_t veclen() const CV_OVERRIDE | ||
| 122 | + { | ||
| 123 | + return kdtree_index_->veclen(); | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + /** | ||
| 127 | + * \returns The amount of memory (in bytes) used by the index. | ||
| 128 | + */ | ||
| 129 | + int usedMemory() const CV_OVERRIDE | ||
| 130 | + { | ||
| 131 | + return kmeans_index_->usedMemory() + kdtree_index_->usedMemory(); | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + /** | ||
| 135 | + * \brief Builds the index | ||
| 136 | + */ | ||
| 137 | + void buildIndex() CV_OVERRIDE | ||
| 138 | + { | ||
| 139 | + Logger::info("Building kmeans tree...\n"); | ||
| 140 | + kmeans_index_->buildIndex(); | ||
| 141 | + Logger::info("Building kdtree tree...\n"); | ||
| 142 | + kdtree_index_->buildIndex(); | ||
| 143 | + } | ||
| 144 | + | ||
| 145 | + /** | ||
| 146 | + * \brief Saves the index to a stream | ||
| 147 | + * \param stream The stream to save the index to | ||
| 148 | + */ | ||
| 149 | + void saveIndex(FILE* stream) CV_OVERRIDE | ||
| 150 | + { | ||
| 151 | + kmeans_index_->saveIndex(stream); | ||
| 152 | + kdtree_index_->saveIndex(stream); | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + /** | ||
| 156 | + * \brief Loads the index from a stream | ||
| 157 | + * \param stream The stream from which the index is loaded | ||
| 158 | + */ | ||
| 159 | + void loadIndex(FILE* stream) CV_OVERRIDE | ||
| 160 | + { | ||
| 161 | + kmeans_index_->loadIndex(stream); | ||
| 162 | + kdtree_index_->loadIndex(stream); | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + /** | ||
| 166 | + * \returns The index parameters | ||
| 167 | + */ | ||
| 168 | + IndexParams getParameters() const CV_OVERRIDE | ||
| 169 | + { | ||
| 170 | + return index_params_; | ||
| 171 | + } | ||
| 172 | + | ||
| 173 | + /** | ||
| 174 | + * \brief Method that searches for nearest-neighbours | ||
| 175 | + */ | ||
| 176 | + void findNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, const SearchParams& searchParams) CV_OVERRIDE | ||
| 177 | + { | ||
| 178 | + kmeans_index_->findNeighbors(result, vec, searchParams); | ||
| 179 | + kdtree_index_->findNeighbors(result, vec, searchParams); | ||
| 180 | + } | ||
| 181 | + | ||
| 182 | +private: | ||
| 183 | + /** The k-means index */ | ||
| 184 | + KMeansIndex<Distance>* kmeans_index_; | ||
| 185 | + | ||
| 186 | + /** The kd-tree index */ | ||
| 187 | + KDTreeIndex<Distance>* kdtree_index_; | ||
| 188 | + | ||
| 189 | + /** The index parameters */ | ||
| 190 | + const IndexParams index_params_; | ||
| 191 | +}; | ||
| 192 | + | ||
| 193 | +} | ||
| 194 | + | ||
| 195 | +//! @endcond | ||
| 196 | + | ||
| 197 | +#endif //OPENCV_FLANN_COMPOSITE_INDEX_H_ |
| 1 | +/*********************************************************************** | ||
| 2 | + * Software License Agreement (BSD License) | ||
| 3 | + * | ||
| 4 | + * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. | ||
| 5 | + * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. | ||
| 6 | + * | ||
| 7 | + * Redistribution and use in source and binary forms, with or without | ||
| 8 | + * modification, are permitted provided that the following conditions | ||
| 9 | + * are met: | ||
| 10 | + * | ||
| 11 | + * 1. Redistributions of source code must retain the above copyright | ||
| 12 | + * notice, this list of conditions and the following disclaimer. | ||
| 13 | + * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | + * notice, this list of conditions and the following disclaimer in the | ||
| 15 | + * documentation and/or other materials provided with the distribution. | ||
| 16 | + * | ||
| 17 | + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
| 18 | + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| 19 | + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| 20 | + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 21 | + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 22 | + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 23 | + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 24 | + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 25 | + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| 26 | + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 27 | + *************************************************************************/ | ||
| 28 | + | ||
| 29 | + | ||
| 30 | +#ifndef OPENCV_FLANN_CONFIG_H_ | ||
| 31 | +#define OPENCV_FLANN_CONFIG_H_ | ||
| 32 | + | ||
| 33 | +//! @cond IGNORED | ||
| 34 | + | ||
| 35 | +#ifdef FLANN_VERSION_ | ||
| 36 | +#undef FLANN_VERSION_ | ||
| 37 | +#endif | ||
| 38 | +#define FLANN_VERSION_ "1.6.10" | ||
| 39 | + | ||
| 40 | +//! @endcond | ||
| 41 | + | ||
| 42 | +#endif /* OPENCV_FLANN_CONFIG_H_ */ |
| 1 | +/*********************************************************************** | ||
| 2 | + * Software License Agreement (BSD License) | ||
| 3 | + * | ||
| 4 | + * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. | ||
| 5 | + * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. | ||
| 6 | + * | ||
| 7 | + * Redistribution and use in source and binary forms, with or without | ||
| 8 | + * modification, are permitted provided that the following conditions | ||
| 9 | + * are met: | ||
| 10 | + * | ||
| 11 | + * 1. Redistributions of source code must retain the above copyright | ||
| 12 | + * notice, this list of conditions and the following disclaimer. | ||
| 13 | + * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | + * notice, this list of conditions and the following disclaimer in the | ||
| 15 | + * documentation and/or other materials provided with the distribution. | ||
| 16 | + * | ||
| 17 | + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
| 18 | + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| 19 | + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| 20 | + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 21 | + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 22 | + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 23 | + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 24 | + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 25 | + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| 26 | + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 27 | + *************************************************************************/ | ||
| 28 | + | ||
| 29 | + | ||
| 30 | +#ifndef OPENCV_FLANN_DEFINES_H_ | ||
| 31 | +#define OPENCV_FLANN_DEFINES_H_ | ||
| 32 | + | ||
| 33 | +//! @cond IGNORED | ||
| 34 | + | ||
| 35 | +#include "config.h" | ||
| 36 | + | ||
| 37 | +#ifdef FLANN_EXPORT | ||
| 38 | +#undef FLANN_EXPORT | ||
| 39 | +#endif | ||
| 40 | +#ifdef _WIN32 | ||
| 41 | +/* win32 dll export/import directives */ | ||
| 42 | + #ifdef FLANN_EXPORTS | ||
| 43 | + #define FLANN_EXPORT __declspec(dllexport) | ||
| 44 | + #elif defined(FLANN_STATIC) | ||
| 45 | + #define FLANN_EXPORT | ||
| 46 | + #else | ||
| 47 | + #define FLANN_EXPORT __declspec(dllimport) | ||
| 48 | + #endif | ||
| 49 | +#else | ||
| 50 | +/* unix needs nothing */ | ||
| 51 | + #define FLANN_EXPORT | ||
| 52 | +#endif | ||
| 53 | + | ||
| 54 | + | ||
| 55 | +#undef FLANN_PLATFORM_32_BIT | ||
| 56 | +#undef FLANN_PLATFORM_64_BIT | ||
| 57 | +#if defined __amd64__ || defined __x86_64__ || defined _WIN64 || defined _M_X64 | ||
| 58 | +#define FLANN_PLATFORM_64_BIT | ||
| 59 | +#else | ||
| 60 | +#define FLANN_PLATFORM_32_BIT | ||
| 61 | +#endif | ||
| 62 | + | ||
| 63 | + | ||
| 64 | +#undef FLANN_ARRAY_LEN | ||
| 65 | +#define FLANN_ARRAY_LEN(a) (sizeof(a)/sizeof(a[0])) | ||
| 66 | + | ||
| 67 | +namespace cvflann { | ||
| 68 | + | ||
| 69 | +/* Nearest neighbour index algorithms */ | ||
| 70 | +enum flann_algorithm_t | ||
| 71 | +{ | ||
| 72 | + FLANN_INDEX_LINEAR = 0, | ||
| 73 | + FLANN_INDEX_KDTREE = 1, | ||
| 74 | + FLANN_INDEX_KMEANS = 2, | ||
| 75 | + FLANN_INDEX_COMPOSITE = 3, | ||
| 76 | + FLANN_INDEX_KDTREE_SINGLE = 4, | ||
| 77 | + FLANN_INDEX_HIERARCHICAL = 5, | ||
| 78 | + FLANN_INDEX_LSH = 6, | ||
| 79 | + FLANN_INDEX_SAVED = 254, | ||
| 80 | + FLANN_INDEX_AUTOTUNED = 255, | ||
| 81 | + | ||
| 82 | + // deprecated constants, should use the FLANN_INDEX_* ones instead | ||
| 83 | + LINEAR = 0, | ||
| 84 | + KDTREE = 1, | ||
| 85 | + KMEANS = 2, | ||
| 86 | + COMPOSITE = 3, | ||
| 87 | + KDTREE_SINGLE = 4, | ||
| 88 | + SAVED = 254, | ||
| 89 | + AUTOTUNED = 255 | ||
| 90 | +}; | ||
| 91 | + | ||
| 92 | + | ||
| 93 | + | ||
| 94 | +enum flann_centers_init_t | ||
| 95 | +{ | ||
| 96 | + FLANN_CENTERS_RANDOM = 0, | ||
| 97 | + FLANN_CENTERS_GONZALES = 1, | ||
| 98 | + FLANN_CENTERS_KMEANSPP = 2, | ||
| 99 | + FLANN_CENTERS_GROUPWISE = 3, | ||
| 100 | + | ||
| 101 | + // deprecated constants, should use the FLANN_CENTERS_* ones instead | ||
| 102 | + CENTERS_RANDOM = 0, | ||
| 103 | + CENTERS_GONZALES = 1, | ||
| 104 | + CENTERS_KMEANSPP = 2 | ||
| 105 | +}; | ||
| 106 | + | ||
| 107 | +enum flann_log_level_t | ||
| 108 | +{ | ||
| 109 | + FLANN_LOG_NONE = 0, | ||
| 110 | + FLANN_LOG_FATAL = 1, | ||
| 111 | + FLANN_LOG_ERROR = 2, | ||
| 112 | + FLANN_LOG_WARN = 3, | ||
| 113 | + FLANN_LOG_INFO = 4 | ||
| 114 | +}; | ||
| 115 | + | ||
| 116 | +enum flann_distance_t | ||
| 117 | +{ | ||
| 118 | + FLANN_DIST_EUCLIDEAN = 1, | ||
| 119 | + FLANN_DIST_L2 = 1, | ||
| 120 | + FLANN_DIST_MANHATTAN = 2, | ||
| 121 | + FLANN_DIST_L1 = 2, | ||
| 122 | + FLANN_DIST_MINKOWSKI = 3, | ||
| 123 | + FLANN_DIST_MAX = 4, | ||
| 124 | + FLANN_DIST_HIST_INTERSECT = 5, | ||
| 125 | + FLANN_DIST_HELLINGER = 6, | ||
| 126 | + FLANN_DIST_CHI_SQUARE = 7, | ||
| 127 | + FLANN_DIST_CS = 7, | ||
| 128 | + FLANN_DIST_KULLBACK_LEIBLER = 8, | ||
| 129 | + FLANN_DIST_KL = 8, | ||
| 130 | + FLANN_DIST_HAMMING = 9, | ||
| 131 | + FLANN_DIST_DNAMMING = 10, | ||
| 132 | + | ||
| 133 | + // deprecated constants, should use the FLANN_DIST_* ones instead | ||
| 134 | + EUCLIDEAN = 1, | ||
| 135 | + MANHATTAN = 2, | ||
| 136 | + MINKOWSKI = 3, | ||
| 137 | + MAX_DIST = 4, | ||
| 138 | + HIST_INTERSECT = 5, | ||
| 139 | + HELLINGER = 6, | ||
| 140 | + CS = 7, | ||
| 141 | + KL = 8, | ||
| 142 | + KULLBACK_LEIBLER = 8 | ||
| 143 | +}; | ||
| 144 | + | ||
| 145 | +enum flann_datatype_t | ||
| 146 | +{ | ||
| 147 | + FLANN_INT8 = 0, | ||
| 148 | + FLANN_INT16 = 1, | ||
| 149 | + FLANN_INT32 = 2, | ||
| 150 | + FLANN_INT64 = 3, | ||
| 151 | + FLANN_UINT8 = 4, | ||
| 152 | + FLANN_UINT16 = 5, | ||
| 153 | + FLANN_UINT32 = 6, | ||
| 154 | + FLANN_UINT64 = 7, | ||
| 155 | + FLANN_FLOAT32 = 8, | ||
| 156 | + FLANN_FLOAT64 = 9 | ||
| 157 | +}; | ||
| 158 | + | ||
| 159 | +enum | ||
| 160 | +{ | ||
| 161 | + FLANN_CHECKS_UNLIMITED = -1, | ||
| 162 | + FLANN_CHECKS_AUTOTUNED = -2 | ||
| 163 | +}; | ||
| 164 | + | ||
| 165 | +} | ||
| 166 | + | ||
| 167 | +//! @endcond | ||
| 168 | + | ||
| 169 | +#endif /* OPENCV_FLANN_DEFINES_H_ */ |
-
请 注册 或 登录 后发表评论