2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "Features/ORBExtractorFactory.h"
19 #include "ImageMathUtil.h"
21 #include <opencv/cv.h>
23 namespace MediaVision {
25 ORBExtractorFactory::ORBExtractorFactory(
27 size_t maximumFeaturesNumber)
29 setScaleFactor(scaleFactor);
30 setMaximumFeaturesNumber(maximumFeaturesNumber);
33 cv::Ptr<FeatureExtractor> ORBExtractorFactory::buildFeatureExtractor()
35 cv::Ptr<FeatureExtractor> featureExtractor(new FeatureExtractor());
37 cv::Ptr<cv::OrbFeatureDetector> detector(
39 m_maximumFeaturesNumber,
42 cv::Ptr<cv::OrbDescriptorExtractor> extractor = detector;
44 featureExtractor->setFeatureDetector(detector, KT_ORB);
45 featureExtractor->setDescriptorExtractor(extractor, DT_ORB);
46 featureExtractor->setRecognitionRateMetric(computeRecognitionRate);
48 return featureExtractor;
51 float ORBExtractorFactory::getScaleFactor() const
56 void ORBExtractorFactory::setScaleFactor(float scaleFactor)
58 m_scaleFactor = scaleFactor;
61 size_t ORBExtractorFactory::getMaximumFeaturesNumber() const
66 void ORBExtractorFactory::setMaximumFeaturesNumber(size_t maximumFeaturesNumber)
68 m_maximumFeaturesNumber = maximumFeaturesNumber;
71 float ORBExtractorFactory::computeRecognitionRate(
73 const std::vector<cv::KeyPoint>& keypoints)
75 const size_t numberOfKeypoints = keypoints.size();
77 /* it is impossible to calculate the perspective transformation parameters
78 * if number of key points less than MinimumNumberOfFeatures (4) */
79 if (numberOfKeypoints < MinimumNumberOfFeatures)
82 static const size_t xCellsNumber = 10u;
83 static const size_t yCellsNumber = 10u;
85 cv::Mat cells[xCellsNumber][yCellsNumber];
86 size_t accumulationCounter[xCellsNumber][yCellsNumber];
88 const size_t cellWidth = image.cols / xCellsNumber;
89 const size_t cellHeight = image.rows / yCellsNumber;
91 for (size_t x = 0u; x < xCellsNumber; ++x) {
92 for (size_t y = 0u; y < yCellsNumber; ++y) {
93 cells[x][y] = image(cv::Rect(
99 accumulationCounter[x][y] = 0;
103 for (size_t i = 0u; i < numberOfKeypoints; ++i) {
104 size_t xCellIdx = keypoints[i].pt.x / cellWidth;
105 if (xCellIdx >= xCellsNumber)
106 xCellIdx = xCellsNumber - 1;
108 size_t yCellIdx = keypoints[i].pt.y / cellHeight;
109 if (yCellIdx >= yCellsNumber)
110 yCellIdx = yCellsNumber - 1;
112 ++(accumulationCounter[xCellIdx][yCellIdx]);
115 const float exceptedNumber = numberOfKeypoints /
116 (float)(xCellsNumber * yCellsNumber);
118 float distributedEvaluation = 0.f;
120 for (size_t x = 0u; x < xCellsNumber; ++x) {
121 for (size_t y = 0u; y < yCellsNumber; ++y) {
122 distributedEvaluation += (accumulationCounter[x][y] - exceptedNumber) *
123 (accumulationCounter[x][y] - exceptedNumber) / exceptedNumber;
127 float maximumDistributedEvaluation = (xCellsNumber * yCellsNumber - 1) *
130 maximumDistributedEvaluation += (numberOfKeypoints - exceptedNumber) *
131 (numberOfKeypoints - exceptedNumber) / exceptedNumber;
133 distributedEvaluation = 1 -
134 (distributedEvaluation / maximumDistributedEvaluation);
136 /* Exponentiation to find an approximate confidence value based on the
137 * number of key points on the image. */
138 const float cardinalityEvaluation = pow(-0.9, numberOfKeypoints - 3) + 1.0f;
141 return distributedEvaluation * cardinalityEvaluation;