560005fba06db2530ccd7fb90df891c76cee8313
[profile/ivi/opencv.git] / modules / features2d / src / dynamic.cpp
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) 2000-2008, Intel Corporation, all rights reserved.
14  // Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved.
15  // Third party copyrights are property of their respective owners.
16  //
17  // Redistribution and use in source and binary forms, with or without modification,
18  // are permitted provided that the following conditions are met:
19  //
20  //   * Redistribution's of source code must retain the above copyright notice,
21  //     this list of conditions and the following disclaimer.
22  //
23  //   * Redistribution's in binary form must reproduce the above copyright notice,
24  //     this list of conditions and the following disclaimer in the documentation
25  //     and/or other materials provided with the distribution.
26  //
27  //   * The name of the copyright holders may not be used to endorse or promote products
28  //     derived from this software without specific prior written permission.
29  //
30  // This software is provided by the copyright holders and contributors "as is" and
31  // any express or implied warranties, including, but not limited to, the implied
32  // warranties of merchantability and fitness for a particular purpose are disclaimed.
33  // In no event shall the Intel Corporation or contributors be liable for any direct,
34  // indirect, incidental, special, exemplary, or consequential damages
35  // (including, but not limited to, procurement of substitute goods or services;
36  // loss of use, data, or profits; or business interruption) however caused
37  // and on any theory of liability, whether in contract, strict liability,
38  // or tort (including negligence or otherwise) arising in any way out of
39  // the use of this software, even if advised of the possibility of such damage.
40  //
41  //M*/
42
43 #include "precomp.hpp"
44 namespace cv
45 {
46
47 DynamicAdaptedFeatureDetector::DynamicAdaptedFeatureDetector(const Ptr<AdjusterAdapter>& a,
48                                          int min_features, int max_features, int max_iters ) :
49         escape_iters_(max_iters), min_features_(min_features), max_features_(max_features), adjuster_(a)
50 {}
51
52 bool DynamicAdaptedFeatureDetector::empty() const
53 {
54     return !adjuster_ || adjuster_->empty();
55 }
56
57 void DynamicAdaptedFeatureDetector::detectImpl(InputArray _image, std::vector<KeyPoint>& keypoints, InputArray _mask) const
58 {
59     Mat image = _image.getMat(), mask = _mask.getMat();
60
61     //for oscillation testing
62     bool down = false;
63     bool up = false;
64
65     //flag for whether the correct threshhold has been reached
66     bool thresh_good = false;
67
68     Ptr<AdjusterAdapter> adjuster = adjuster_->clone();
69
70     //break if the desired number hasn't been reached.
71     int iter_count = escape_iters_;
72
73     while( iter_count > 0 && !(down && up) && !thresh_good && adjuster->good() )
74     {
75         keypoints.clear();
76
77         //the adjuster takes care of calling the detector with updated parameters
78         adjuster->detect(image, keypoints,mask);
79
80         if( int(keypoints.size()) < min_features_ )
81         {
82             down = true;
83             adjuster->tooFew(min_features_, (int)keypoints.size());
84         }
85         else if( int(keypoints.size()) > max_features_ )
86         {
87             up = true;
88             adjuster->tooMany(max_features_, (int)keypoints.size());
89         }
90         else
91             thresh_good = true;
92
93         iter_count--;
94     }
95
96 }
97
98 FastAdjuster::FastAdjuster( int init_thresh, bool nonmax, int min_thresh, int max_thresh ) :
99     thresh_(init_thresh), nonmax_(nonmax), init_thresh_(init_thresh),
100     min_thresh_(min_thresh), max_thresh_(max_thresh)
101 {}
102
103 void FastAdjuster::detectImpl(InputArray image, std::vector<KeyPoint>& keypoints, InputArray mask) const
104 {
105     FastFeatureDetector(thresh_, nonmax_).detect(image, keypoints, mask);
106 }
107
108 void FastAdjuster::tooFew(int, int)
109 {
110     //fast is easy to adjust
111     thresh_--;
112 }
113
114 void FastAdjuster::tooMany(int, int)
115 {
116     //fast is easy to adjust
117     thresh_++;
118 }
119
120 //return whether or not the threshhold is beyond
121 //a useful point
122 bool FastAdjuster::good() const
123 {
124     return (thresh_ > min_thresh_) && (thresh_ < max_thresh_);
125 }
126
127 Ptr<AdjusterAdapter> FastAdjuster::clone() const
128 {
129     Ptr<AdjusterAdapter> cloned_obj(new FastAdjuster( init_thresh_, nonmax_, min_thresh_, max_thresh_ ));
130     return cloned_obj;
131 }
132
133 StarAdjuster::StarAdjuster(double initial_thresh, double min_thresh, double max_thresh) :
134     thresh_(initial_thresh), init_thresh_(initial_thresh),
135     min_thresh_(min_thresh), max_thresh_(max_thresh)
136 {}
137
138 void StarAdjuster::detectImpl(InputArray image, std::vector<KeyPoint>& keypoints, InputArray mask) const
139 {
140     StarFeatureDetector detector_tmp(16, cvRound(thresh_), 10, 8, 3);
141     detector_tmp.detect(image, keypoints, mask);
142 }
143
144 void StarAdjuster::tooFew(int, int)
145 {
146     thresh_ *= 0.9;
147     if (thresh_ < 1.1)
148             thresh_ = 1.1;
149 }
150
151 void StarAdjuster::tooMany(int, int)
152 {
153     thresh_ *= 1.1;
154 }
155
156 bool StarAdjuster::good() const
157 {
158     return (thresh_ > min_thresh_) && (thresh_ < max_thresh_);
159 }
160
161 Ptr<AdjusterAdapter> StarAdjuster::clone() const
162 {
163     Ptr<AdjusterAdapter> cloned_obj(new StarAdjuster( init_thresh_, min_thresh_, max_thresh_ ));
164     return cloned_obj;
165 }
166
167 SurfAdjuster::SurfAdjuster( double initial_thresh, double min_thresh, double max_thresh ) :
168     thresh_(initial_thresh), init_thresh_(initial_thresh),
169     min_thresh_(min_thresh), max_thresh_(max_thresh)
170 {}
171
172 void SurfAdjuster::detectImpl(InputArray image, std::vector<KeyPoint>& keypoints, InputArray mask) const
173 {
174     Ptr<FeatureDetector> surf = FeatureDetector::create("SURF");
175     surf->set("hessianThreshold", thresh_);
176     surf->detect(image, keypoints, mask);
177 }
178
179 void SurfAdjuster::tooFew(int, int)
180 {
181     thresh_ *= 0.9;
182     if (thresh_ < 1.1)
183             thresh_ = 1.1;
184 }
185
186 void SurfAdjuster::tooMany(int, int)
187 {
188     thresh_ *= 1.1;
189 }
190
191 //return whether or not the threshhold is beyond
192 //a useful point
193 bool SurfAdjuster::good() const
194 {
195     return (thresh_ > min_thresh_) && (thresh_ < max_thresh_);
196 }
197
198 Ptr<AdjusterAdapter> SurfAdjuster::clone() const
199 {
200     Ptr<AdjusterAdapter> cloned_obj(new SurfAdjuster( init_thresh_, min_thresh_, max_thresh_ ));
201     return cloned_obj;
202 }
203
204 Ptr<AdjusterAdapter> AdjusterAdapter::create( const String& detectorType )
205 {
206     Ptr<AdjusterAdapter> adapter;
207
208     if( !detectorType.compare( "FAST" ) )
209     {
210         adapter = makePtr<FastAdjuster>();
211     }
212     else if( !detectorType.compare( "STAR" ) )
213     {
214         adapter = makePtr<StarAdjuster>();
215     }
216     else if( !detectorType.compare( "SURF" ) )
217     {
218         adapter = makePtr<SurfAdjuster>();
219     }
220
221     return adapter;
222 }
223
224 }