Berkeley SfM
keypoint_detector.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, The Regents of the University of California (Regents).
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following
14  * disclaimer in the documentation and/or other materials provided
15  * with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Please contact the author(s) of this library if you have any questions.
34  * Authors: Erik Nelson ( eanelson@eecs.berkeley.edu )
35  * David Fridovich-Keil ( dfk@eecs.berkeley.edu )
36  */
37 
38 #include "keypoint_detector.h"
39 
40 #include <glog/logging.h>
41 
42 namespace bsfm {
43 
45  : adaptive_(false),
46  adaptive_min_(0),
47  adaptive_max_(0),
48  adaptive_iters_(0) {
49  cv::initModule_nonfree();
50 }
51 
52 bool KeypointDetector::SetDetector(const std::string& detector_type) {
53  // Set the detector type.
54  detector_type_ = detector_type;
55  bool valid_detector_type = true;
56 
57  // Create an OpenCV feature detector. SURF, FAST, and STAR support adjusters.
58  if (detector_type.compare("SURF") == 0) {
59 
60  if (adaptive_) {
61  cv::Ptr<cv::AdjusterAdapter> adjuster(
62  cv::AdjusterAdapter::create("SURF"));
63  detector_ =
64  cv::Ptr<cv::FeatureDetector>(new cv::DynamicAdaptedFeatureDetector(
66  } else {
67  detector_ = cv::FeatureDetector::create("SURF");
68  }
69 
70  } else if (detector_type.compare("FAST") == 0) {
71 
72  if (adaptive_) {
73  cv::Ptr<cv::AdjusterAdapter> adjuster(
74  cv::AdjusterAdapter::create("FAST"));
75  detector_ =
76  cv::Ptr<cv::FeatureDetector>(new cv::DynamicAdaptedFeatureDetector(
78  } else {
79  detector_ = cv::FeatureDetector::create("FAST");
80  }
81 
82  } else if (detector_type.compare("STAR") == 0) {
83 
84  if (adaptive_) {
85  cv::Ptr<cv::AdjusterAdapter> adjuster(
86  cv::AdjusterAdapter::create("STAR"));
87  detector_ =
88  cv::Ptr<cv::FeatureDetector>(new cv::DynamicAdaptedFeatureDetector(
90  } else {
91  detector_ = cv::FeatureDetector::create("STAR");
92  }
93 
94  } else if (detector_type.compare("SIFT") == 0) {
95 
96  detector_ = cv::FeatureDetector::create("SIFT");
97 
98  } else if (detector_type.compare("ORB") == 0) {
99 
100  detector_ = cv::FeatureDetector::create("ORB");
101 
102  } else if (detector_type.compare("BRISK") == 0) {
103 
104  detector_ = cv::FeatureDetector::create("BRISK");
105 
106  } else if (detector_type.compare("MSER") == 0) {
107 
108  detector_ = cv::FeatureDetector::create("MSER");
109 
110  } else if (detector_type.compare("GFTT") == 0) {
111 
112  detector_ = cv::FeatureDetector::create("GFTT");
113 
114  } else if (detector_type.compare("HARRIS") == 0) {
115 
116  detector_ = cv::FeatureDetector::create("HARRIS");
117 
118  } else if (detector_type.compare("DENSE") == 0) {
119 
120  detector_ = cv::FeatureDetector::create("Dense");
121 
122  } else if (detector_type.compare("SIMPLEBLOB") == 0) {
123 
124  detector_ = cv::FeatureDetector::create("SimpleBlob");
125 
126  } else {
127  VLOG(1) << "Detector type \"" << detector_type
128  << "\"is not available. Defaulting to FAST.";
129 
130  // Default to a FAST detector.
131  if (adaptive_) {
132  cv::Ptr<cv::AdjusterAdapter> adjuster(
133  cv::AdjusterAdapter::create("FAST"));
134  detector_ =
135  cv::Ptr<cv::FeatureDetector>(new cv::DynamicAdaptedFeatureDetector(
137  } else {
138  detector_ = cv::FeatureDetector::create("FAST");
139  }
140 
141  valid_detector_type = false;
142  detector_type_ = "FAST";
143  }
144 
145  return valid_detector_type;
146 }
147 
149  KeypointList& keypoints_out) {
150  // Make the user has called SetDetector().
151  if (detector_type_.empty()) {
152  VLOG(1) << "Detector has not been specified via SetDetector(). Failed to "
153  "detect keypoints.";
154  return false;
155  }
156  CHECK(detector_) << "The feature detector is null.";
157 
158  // Clear the output.
159  keypoints_out.clear();
160 
161  // Convert the input image to OpenCV's format. Note that features must be
162  // detected on the grayscale image, and that the image format must be CV_8U.
163  cv::Mat cv_image;
164  image.ToCV(cv_image);
165  cv_image.convertTo(cv_image, CV_8U, 255);
166 
167  // Detect keypoints in the image.
168  try {
169  detector_->detect(cv_image, keypoints_out);
170  } catch (const std::exception& e) {
171  VLOG(1) << "Failed to detect keypoints: " << e.what();
172  return false;
173  }
174 
175  return true;
176 }
177 
178 // Turn adaptive features on.
179 void KeypointDetector::SetAdaptiveOn(unsigned int min, unsigned int max,
180  unsigned int iters) {
182  VLOG(1) << "The detector type \"" << detector_type_
183  << "\" does not support adaptive feature count adjustment. Type "
184  "must be one of {FAST, SURF, STAR}";
185  return;
186  }
187 
188  adaptive_ = true;
189  adaptive_min_ = min;
190  adaptive_max_ = max;
191  adaptive_iters_ = iters;
192 
193  // If the feature detector is already set, re-initialize it.
194  if (detector_ != nullptr) {
196  }
197 }
198 
199 // Turn adaptive feature counts off.
202  VLOG(1) << "The detector type \"" << detector_type_
203  << "\" does not support adaptive feature count adjustment, and "
204  "therefore is already static.";
205  return;
206  }
207 
208  adaptive_ = false;
209  adaptive_min_ = 0;
210  adaptive_max_ = 0;
211  adaptive_iters_ = 0;
212 
213  // If the feature detector is already set, re-initialize it.
214  if (detector_ != nullptr) {
216  }
217 }
218 
219 // Adaptive adjustment is supported with FAST, SURF, and STAR features.
221  if (detector_type_.compare("FAST") == 0 ||
222  detector_type_.compare("SURF") == 0 ||
223  detector_type_.compare("STAR") == 0) {
224  return true;
225  }
226 
227  return false;
228 }
229 
230 } //\namespace bsfm
bool DetectKeypoints(const Image &image, KeypointList &keypoints_out)
cv::Ptr< cv::FeatureDetector > detector_
bool SupportsAdaptiveAdjustment() const
::std::vector< Keypoint > KeypointList
Definition: types.h:80
bool SetDetector(const std::string &detector_type)
Definition: camera.cpp:50
void ToCV(cv::Mat &out) const
Definition: image.cpp:72
void SetAdaptiveOn(unsigned int min, unsigned int max, unsigned int iters)