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) 2008, Willow Garage Inc., 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 Intel Corporation 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/*
43OpenCV wrapper of reference implementation of
44[1] Fast Explicit Diffusion for Accelerated Features in Nonlinear Scale Spaces.
45Pablo F. Alcantarilla, J. Nuevo and Adrien Bartoli.
46In British Machine Vision Conference (BMVC), Bristol, UK, September 2013
47http://www.robesafe.com/personal/pablo.alcantarilla/papers/Alcantarilla13bmvc.pdf
48@author Eugene Khvedchenya <ekhvedchenya@gmail.com>
49*/
50
51#include "precomp.hpp"
52#include "kaze/AKAZEFeatures.h"
53
54#include <iostream>
55
56namespace cv
57{
58 using namespace std;
59
60 class AKAZE_Impl : public AKAZE
61 {
62 public:
63 AKAZE_Impl(DescriptorType _descriptor_type, int _descriptor_size, int _descriptor_channels,
64 float _threshold, int _octaves, int _sublevels, KAZE::DiffusivityType _diffusivity, int _max_points)
65 : descriptor(_descriptor_type)
66 , descriptor_channels(_descriptor_channels)
67 , descriptor_size(_descriptor_size)
68 , threshold(_threshold)
69 , octaves(_octaves)
70 , sublevels(_sublevels)
71 , diffusivity(_diffusivity)
72 , max_points(_max_points)
73 {
74 }
75
76 virtual ~AKAZE_Impl() CV_OVERRIDE
77 {
78
79 }
80
81 void setDescriptorType(DescriptorType dtype) CV_OVERRIDE{ descriptor = dtype; }
82 DescriptorType getDescriptorType() const CV_OVERRIDE{ return descriptor; }
83
84 void setDescriptorSize(int dsize) CV_OVERRIDE { descriptor_size = dsize; }
85 int getDescriptorSize() const CV_OVERRIDE { return descriptor_size; }
86
87 void setDescriptorChannels(int dch) CV_OVERRIDE { descriptor_channels = dch; }
88 int getDescriptorChannels() const CV_OVERRIDE { return descriptor_channels; }
89
90 void setThreshold(double threshold_) CV_OVERRIDE { threshold = (float)threshold_; }
91 double getThreshold() const CV_OVERRIDE { return threshold; }
92
93 void setNOctaves(int octaves_) CV_OVERRIDE { octaves = octaves_; }
94 int getNOctaves() const CV_OVERRIDE { return octaves; }
95
96 void setNOctaveLayers(int octaveLayers_) CV_OVERRIDE { sublevels = octaveLayers_; }
97 int getNOctaveLayers() const CV_OVERRIDE { return sublevels; }
98
99 void setDiffusivity(KAZE::DiffusivityType diff_) CV_OVERRIDE{ diffusivity = diff_; }
100 KAZE::DiffusivityType getDiffusivity() const CV_OVERRIDE{ return diffusivity; }
101
102 void setMaxPoints(int max_points_) CV_OVERRIDE { max_points = max_points_; }
103 int getMaxPoints() const CV_OVERRIDE { return max_points; }
104
105 // returns the descriptor size in bytes
106 int descriptorSize() const CV_OVERRIDE
107 {
108 switch (descriptor)
109 {
110 case DESCRIPTOR_KAZE:
111 case DESCRIPTOR_KAZE_UPRIGHT:
112 return 64;
113
114 case DESCRIPTOR_MLDB:
115 case DESCRIPTOR_MLDB_UPRIGHT:
116 // We use the full length binary descriptor -> 486 bits
117 if (descriptor_size == 0)
118 {
119 int t = (6 + 36 + 120) * descriptor_channels;
120 return divUp(a: t, b: 8);
121 }
122 else
123 {
124 // We use the random bit selection length binary descriptor
125 return divUp(a: descriptor_size, b: 8);
126 }
127
128 default:
129 return -1;
130 }
131 }
132
133 // returns the descriptor type
134 int descriptorType() const CV_OVERRIDE
135 {
136 switch (descriptor)
137 {
138 case DESCRIPTOR_KAZE:
139 case DESCRIPTOR_KAZE_UPRIGHT:
140 return CV_32F;
141
142 case DESCRIPTOR_MLDB:
143 case DESCRIPTOR_MLDB_UPRIGHT:
144 return CV_8U;
145
146 default:
147 return -1;
148 }
149 }
150
151 // returns the default norm type
152 int defaultNorm() const CV_OVERRIDE
153 {
154 switch (descriptor)
155 {
156 case DESCRIPTOR_KAZE:
157 case DESCRIPTOR_KAZE_UPRIGHT:
158 return NORM_L2;
159
160 case DESCRIPTOR_MLDB:
161 case DESCRIPTOR_MLDB_UPRIGHT:
162 return NORM_HAMMING;
163
164 default:
165 return -1;
166 }
167 }
168
169 void detectAndCompute(InputArray image, InputArray mask,
170 std::vector<KeyPoint>& keypoints,
171 OutputArray descriptors,
172 bool useProvidedKeypoints) CV_OVERRIDE
173 {
174 CV_INSTRUMENT_REGION();
175
176 CV_Assert( ! image.empty() );
177
178 AKAZEOptions options;
179 options.descriptor = descriptor;
180 options.descriptor_channels = descriptor_channels;
181 options.descriptor_size = descriptor_size;
182 options.img_width = image.cols();
183 options.img_height = image.rows();
184 options.dthreshold = threshold;
185 options.omax = octaves;
186 options.nsublevels = sublevels;
187 options.diffusivity = diffusivity;
188
189 AKAZEFeatures impl(options);
190 impl.Create_Nonlinear_Scale_Space(img: image);
191
192 if (!useProvidedKeypoints)
193 {
194 impl.Feature_Detection(kpts&: keypoints);
195 }
196
197 if (!mask.empty())
198 {
199 KeyPointsFilter::runByPixelsMask(keypoints, mask: mask.getMat());
200 }
201
202 if (max_points > 0 && (int)keypoints.size() > max_points) {
203 std::partial_sort(first: keypoints.begin(), middle: keypoints.begin() + max_points, last: keypoints.end(),
204 comp: [](const cv::KeyPoint& k1, const cv::KeyPoint& k2) {return k1.response > k2.response;});
205 keypoints.erase(first: keypoints.begin() + max_points, last: keypoints.end());
206 }
207
208 if(descriptors.needed())
209 {
210 impl.Compute_Descriptors(kpts&: keypoints, desc: descriptors);
211
212 CV_Assert((descriptors.empty() || descriptors.cols() == descriptorSize()));
213 CV_Assert((descriptors.empty() || (descriptors.type() == descriptorType())));
214 }
215 }
216
217 void write(FileStorage& fs) const CV_OVERRIDE
218 {
219 writeFormat(fs);
220 fs << "name" << getDefaultName();
221 fs << "descriptor" << descriptor;
222 fs << "descriptor_channels" << descriptor_channels;
223 fs << "descriptor_size" << descriptor_size;
224 fs << "threshold" << threshold;
225 fs << "octaves" << octaves;
226 fs << "sublevels" << sublevels;
227 fs << "diffusivity" << diffusivity;
228 fs << "max_points" << max_points;
229 }
230
231 void read(const FileNode& fn) CV_OVERRIDE
232 {
233 // if node is empty, keep previous value
234 if (!fn["descriptor"].empty())
235 descriptor = static_cast<DescriptorType>((int)fn["descriptor"]);
236 if (!fn["descriptor_channels"].empty())
237 descriptor_channels = (int)fn["descriptor_channels"];
238 if (!fn["descriptor_size"].empty())
239 descriptor_size = (int)fn["descriptor_size"];
240 if (!fn["threshold"].empty())
241 threshold = (float)fn["threshold"];
242 if (!fn["octaves"].empty())
243 octaves = (int)fn["octaves"];
244 if (!fn["sublevels"].empty())
245 sublevels = (int)fn["sublevels"];
246 if (!fn["diffusivity"].empty())
247 diffusivity = static_cast<KAZE::DiffusivityType>((int)fn["diffusivity"]);
248 if (!fn["max_points"].empty())
249 max_points = (int)fn["max_points"];
250 }
251
252 DescriptorType descriptor;
253 int descriptor_channels;
254 int descriptor_size;
255 float threshold;
256 int octaves;
257 int sublevels;
258 KAZE::DiffusivityType diffusivity;
259 int max_points;
260 };
261
262 Ptr<AKAZE> AKAZE::create(DescriptorType descriptor_type,
263 int descriptor_size, int descriptor_channels,
264 float threshold, int octaves,
265 int sublevels, KAZE::DiffusivityType diffusivity, int max_points)
266 {
267 return makePtr<AKAZE_Impl>(a1: descriptor_type, a1: descriptor_size, a1: descriptor_channels,
268 a1: threshold, a1: octaves, a1: sublevels, a1: diffusivity, a1: max_points);
269 }
270
271 String AKAZE::getDefaultName() const
272 {
273 return (Feature2D::getDefaultName() + ".AKAZE");
274 }
275
276}
277

source code of opencv/modules/features2d/src/akaze.cpp