detectors.cc

00001 /*
00002 
00003     This file is part of the FAST-ER machine learning system.
00004     Copyright (C) 2008  Edward Rosten and Los Alamos National Laboratory
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License along
00017     with this program; if not, write to the Free Software Foundation, Inc.,
00018     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00019 */
00020 #include "detectors.h"
00021 #include "harrislike.h"
00022 #include "dog.h"
00023 #ifdef USESUSAN
00024     #include "susan.h"
00025 #endif
00026 #include "cvd_fast.h"
00027 //#include "faster_block.h"
00028 #include "faster_detector.h"
00029 
00030 #include <memory>
00031 #include <cstdlib>
00032 #include <gvars3/instances.h>
00033 
00034 using namespace std;
00035 using namespace CVD;
00036 using namespace GVars3;
00037 
00038 /** This takes a detector which requires a threshold and uses binary search to get as
00039 close as possible to the requested number of corners.
00040 
00041 @param i The image in which to detect corners.
00042 @param c The detected corners to be returned.
00043 @param N The target number of corners.
00044 @param detector The corner detector.
00045 @ingroup gDetect
00046 */
00047 int binary_search_threshold(const Image<byte>& i, vector<ImageRef>& c, unsigned int N, const DetectT& detector)
00048 {
00049     //Corners for high, low and midpoint thresholds.
00050     vector<ImageRef> ch, cl, cm;
00051     
00052     //The high and low thresholds.
00053     unsigned int t_high = 256;
00054     unsigned int t_low = 0;
00055 
00056 
00057     detector(i, ch, t_high);
00058     detector(i, cl, t_low);
00059 
00060     while(t_high > t_low + 1)
00061     {
00062     
00063         cm.clear();
00064         unsigned int t = (t_high + t_low    ) / 2;
00065         detector(i, cm, t);
00066 
00067         if(cm.size() == N)
00068         {
00069             c = cm;
00070             return t;
00071         }
00072         else if(cm.size() < N) //If we detected too few points, then the t is too high
00073         {
00074             t_high = t;
00075             ch = cm;
00076         }
00077         else //We detected too many points to t is too low.
00078         {
00079             t_low = t;
00080             cl = cm;
00081         }
00082     }
00083 
00084     //Pick the closest
00085     //If there is ambiguity, go with the lower threshold (more corners).
00086     //The only reason for this is that the evaluation code in the FAST-ER
00087     //system uses this rule.
00088     if( N - ch.size() >= cl.size() - N)
00089     {
00090         c = cl;
00091         return t_low;
00092     }
00093     else
00094     { 
00095         c = ch;
00096         return t_high;
00097     }
00098 }
00099 
00100 ///This class wraps a ::DetectT class with ::binary_search_threshold and presents
00101 ///is as a DetectN class.
00102 ///@ingroup gDetect
00103 struct SearchThreshold:public DetectN
00104 {
00105     ///@param d Detector to wrap. This will be managed by SearchThreshold
00106     SearchThreshold(DetectT* d)
00107     :detector(d)
00108     {
00109     }
00110     
00111     ///Detect corners
00112     ///@param im Image in which to detect corners
00113     ///@param corners Detected corners are inserted in to this array
00114     ///@param N number of corners to detect
00115     virtual void operator()(const Image<byte>& im, vector<ImageRef>& corners, unsigned int N)const
00116     {
00117         int t = binary_search_threshold(im, corners, N, *detector); 
00118     }
00119     
00120     private: 
00121     ///Detector to wrap
00122     auto_ptr<DetectT> detector; 
00123 };
00124 
00125 ///@ingroup gDetect
00126 ///Detector which randomly scatters corners around an image.
00127 struct Random:public DetectN
00128 {
00129     ///Detect corners by scattering points around at random
00130     ///@param im Image in which to detect corners
00131     ///@param corners Detected corners are inserted in to this array
00132     ///@param N number of corners to detect
00133     virtual void operator()(const Image<byte>& im, vector<ImageRef>& corners, unsigned int N)const
00134     {
00135         for(unsigned int i=0; i < N; i++)
00136             corners.push_back(ImageRef(rand() % im.size().x, rand() % im.size().y));
00137     }
00138 };
00139 
00140 ///Very simple factory function for getting detector objects.
00141 ///Paramaters (including the detector type) are drawn from 
00142 ///the GVars database. The parameter "detector" determines the
00143 ///detector type. Valid options are:
00144 ///  - \link ::Random random \endlink Randomly scatter corners around the image.
00145 ///  - \link ::dog dog \endlink Difference of Gaussians detector
00146 ///  - \link ::harrisdog harrisdog \endlink Harris-Laplace (actually implemented as Harris-DoG) detector
00147 ///  - \link ::HarrisDetect harris\endlink Harris detector with Gaussian blur
00148 ///  - \link ::ShiTomasiDetect shitomasi\endlink Shi-Tomasi detector
00149 ///  - \link ::SUSAN susan\endlink Reference implementation of the SUSAN detector
00150 ///  - \link ::fast_9 fast9\endlink libCVD's builtin FAST-9 detector
00151 ///  - \link ::fast_9_old fast9old\endlink libCVD's builtin FAST-9 detector with the old
00152 ///          scoring algorithm, as seen in [Rosten, Drummond 2006].
00153 ///  - \link ::fast_12 fast12\endlink libCVD's builtin FAST-12 detector
00154 ///  - \link ::faster_learn faster2\endlink A FAST-ER detector loaded from a file containing the tree
00155 ///@ingroup gDetect
00156 auto_ptr<DetectN> get_detector()
00157 {
00158     
00159     string d = GV3::get<string>("detector", "fast9", 1);
00160     
00161     if(d == "random")
00162         return auto_ptr<DetectN>(new Random);
00163     else if(d == "dog")
00164         return auto_ptr<DetectN>(new dog);
00165     else if(d == "harrisdog")
00166         return auto_ptr<DetectN>(new harrisdog);
00167     else if(d == "shitomasi")
00168         return auto_ptr<DetectN>(new ShiTomasiDetect);
00169     else if(d == "harris")
00170         return auto_ptr<DetectN>(new HarrisDetect);
00171     #ifdef USESUSAN
00172         else if(d == "susan")
00173             return auto_ptr<DetectN>(new SearchThreshold(new SUSAN));
00174     #endif
00175     else if(d == "fast9")
00176         return auto_ptr<DetectN>(new SearchThreshold(new fast_9));
00177     else if(d == "fast9old")
00178         return auto_ptr<DetectN>(new SearchThreshold(new fast_9_old));
00179     else if(d == "fast12")
00180         return auto_ptr<DetectN>(new SearchThreshold(new fast_12));
00181     else if(d == "faster2")
00182         return auto_ptr<DetectN>(new SearchThreshold(new faster_learn(GV3::get<string>("faster2"))));
00183     else
00184     {
00185         cerr << "Unknown detector: " << d << endl;
00186         exit(1);
00187     }
00188 }

Generated on Mon Mar 2 12:47:12 2009 for FAST-ER by  doxygen 1.5.3