[coding convention] Fixed coding rule violation
[platform/core/api/mediavision.git] / mv_image / image / src / Features / ORBExtractorFactory.cpp
1 /**
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "Features/ORBExtractorFactory.h"
18
19 #include "ImageMathUtil.h"
20
21 #include <opencv/cv.h>
22
23 namespace MediaVision {
24 namespace Image {
25 ORBExtractorFactory::ORBExtractorFactory(
26                 float scaleFactor,
27                 size_t maximumFeaturesNumber)
28 {
29         setScaleFactor(scaleFactor);
30         setMaximumFeaturesNumber(maximumFeaturesNumber);
31 }
32
33 cv::Ptr<FeatureExtractor> ORBExtractorFactory::buildFeatureExtractor()
34 {
35         cv::Ptr<FeatureExtractor> featureExtractor(new FeatureExtractor());
36
37         cv::Ptr<cv::OrbFeatureDetector> detector(
38                         new cv::ORB(
39                                 m_maximumFeaturesNumber,
40                                 m_scaleFactor));
41
42         cv::Ptr<cv::OrbDescriptorExtractor> extractor = detector;
43
44         featureExtractor->setFeatureDetector(detector, KT_ORB);
45         featureExtractor->setDescriptorExtractor(extractor, DT_ORB);
46         featureExtractor->setRecognitionRateMetric(computeRecognitionRate);
47
48         return featureExtractor;
49 }
50
51 float ORBExtractorFactory::getScaleFactor() const
52 {
53         return m_scaleFactor;
54 }
55
56 void ORBExtractorFactory::setScaleFactor(float scaleFactor)
57 {
58         m_scaleFactor = scaleFactor;
59 }
60
61 size_t ORBExtractorFactory::getMaximumFeaturesNumber() const
62 {
63         return m_scaleFactor;
64 }
65
66 void ORBExtractorFactory::setMaximumFeaturesNumber(size_t maximumFeaturesNumber)
67 {
68         m_maximumFeaturesNumber = maximumFeaturesNumber;
69 }
70
71 float ORBExtractorFactory::computeRecognitionRate(
72                 const cv::Mat& image,
73                 const std::vector<cv::KeyPoint>& keypoints)
74 {
75         const size_t numberOfKeypoints = keypoints.size();
76
77         /* it is impossible to calculate the perspective transformation parameters
78          * if number of key points less than MinimumNumberOfFeatures (4) */
79         if (numberOfKeypoints < MinimumNumberOfFeatures)
80                 return 0.f;
81
82         static const size_t xCellsNumber = 10u;
83         static const size_t yCellsNumber = 10u;
84
85         cv::Mat cells[xCellsNumber][yCellsNumber];
86         size_t accumulationCounter[xCellsNumber][yCellsNumber];
87
88         const size_t cellWidth = image.cols / xCellsNumber;
89         const size_t cellHeight = image.rows / yCellsNumber;
90
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(
94                                         x * cellWidth,
95                                         y * cellHeight,
96                                         cellWidth,
97                                         cellHeight));
98
99                         accumulationCounter[x][y] = 0;
100                 }
101         }
102
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;
107
108                 size_t yCellIdx = keypoints[i].pt.y / cellHeight;
109                 if (yCellIdx >= yCellsNumber)
110                         yCellIdx = yCellsNumber - 1;
111
112                 ++(accumulationCounter[xCellIdx][yCellIdx]);
113         }
114
115         const float exceptedNumber = numberOfKeypoints /
116                                 (float)(xCellsNumber * yCellsNumber);
117
118         float distributedEvaluation = 0.f;
119
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;
124                 }
125         }
126
127         float maximumDistributedEvaluation = (xCellsNumber * yCellsNumber - 1) *
128                                                                                         exceptedNumber;
129
130         maximumDistributedEvaluation += (numberOfKeypoints - exceptedNumber) *
131                         (numberOfKeypoints - exceptedNumber) / exceptedNumber;
132
133         distributedEvaluation = 1 -
134                                 (distributedEvaluation / maximumDistributedEvaluation);
135
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;
139
140         /* Result metric */
141         return distributedEvaluation * cardinalityEvaluation;
142 }
143
144 } /* Image */
145 } /* MediaVision */