Berkeley SfM
descriptor_extractor.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 "descriptor_extractor.h"
39 
40 namespace bsfm {
41 
42 bool DescriptorExtractor::SetDescriptor(const std::string& descriptor_type) {
43  // Set the descriptor type.
44  descriptor_type_ = descriptor_type;
45  bool valid_descriptor_type = true;
46 
47  // Create an OpenCV descriptor extractor.
48  if (descriptor_type.compare("SIFT") == 0) {
49  extractor_ = cv::DescriptorExtractor::create("SIFT");
50  } else if (descriptor_type_.compare("SURF") == 0) {
51  extractor_ = cv::DescriptorExtractor::create("SURF");
52  } else if (descriptor_type_.compare("BRIEF") == 0) {
53  extractor_ = cv::DescriptorExtractor::create("BRIEF");
54  } else if (descriptor_type_.compare("BRISK") == 0) {
55  extractor_ = cv::DescriptorExtractor::create("BRISK");
56  } else if (descriptor_type_.compare("FREAK") == 0) {
57  extractor_ = cv::DescriptorExtractor::create("FREAK");
58  } else if (descriptor_type_.compare("ORB") == 0) {
59  extractor_ = cv::DescriptorExtractor::create("ORB");
60  } else {
61  VLOG(1) << "Descriptor type \"" << descriptor_type
62  << "\"is not available. Defaulting to SIFT.";
63  extractor_ = cv::DescriptorExtractor::create("SIFT");
64  valid_descriptor_type = false;
65  descriptor_type_ = "SIFT";
66  }
67 
68  return valid_descriptor_type;
69 }
70 
72  const Image& image, KeypointList& keypoints,
73  std::vector<Feature>& features_out,
74  std::vector<Descriptor>& descriptors_out) {
75  // Make the user has called SetDescriptor().
76  if (descriptor_type_.empty()) {
77  VLOG(1)
78  << "Descriptor has not been specified via SetDescriptor(). Failed to "
79  "extract descriptors.";
80  return false;
81  }
82 
83  CHECK(extractor_) << "The descriptor extractor is null.";
84  features_out.clear();
85 
86  // Convert the input image to OpenCV's format. Note that descriptors must be
87  // extracted on the grayscale image, and that the image format must be CV_8U.
88  cv::Mat cv_image;
89  image.ToCV(cv_image);
90  cv_image.convertTo(cv_image, CV_8U, 255);
91 
92  // Extract descriptors from the provided keypoints in the image.
93  cv::Mat cv_descriptors;
94  try {
95  extractor_->compute(cv_image, keypoints, cv_descriptors);
96  } catch (const std::exception& e) {
97  VLOG(1) << "Failed to extract descriptors: " << e.what();
98  return false;
99  }
100 
101  // Convert the computed OpenCV-type descriptors and keypoints into a list of
102  // features and descriptors.
103  for (size_t ii = 0; ii < keypoints.size(); ++ii) {
104  Feature feature;
105  feature.u_ = keypoints[ii].pt.x;
106  feature.v_ = keypoints[ii].pt.y;
107  features_out.push_back(feature);
108 
109  MatrixXd descriptor_mat;
110  OpenCVToEigenMat<double>(cv_descriptors.row(ii), descriptor_mat);
111 
112  // Need to explicitly convert from matrix to vector.
113  Descriptor descriptor = descriptor_mat.row(0).transpose();
114  descriptors_out.push_back(descriptor);
115  }
116 
117  return true;
118 }
119 
120 } //\namespace bsfm
bool SetDescriptor(const std::string &descriptor_type)
double v_
Definition: feature.h:62
cv::Ptr< cv::DescriptorExtractor > extractor_
double u_
Definition: feature.h:62
::std::vector< Keypoint > KeypointList
Definition: types.h:80
bool DescribeFeatures(const Image &image, KeypointList &keypoints, std::vector< Feature > &features_out, std::vector< Descriptor > &descriptors_out)
Definition: camera.cpp:50
void ToCV(cv::Mat &out) const
Definition: image.cpp:72
::Eigen::Matrix< double, Eigen::Dynamic, 1 > Descriptor
Definition: types.h:83