Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
CornerDetectorGradient.hh
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 #ifndef __CornerDetectorGradient_hh__
27 #define __CornerDetectorGradient_hh__
28 
29 #include "CornerDetectorBase.hh"
30 #include <Filter/StructureTensor.hh>
31 #include <Filter/Gauss.hh>
32 #include <Base/Math/Matrix2x2.hh>
33 
34 
35 namespace BIAS {
36  /**@cond HIDDEN_SYMBOLS
37  @class Feat
38  @ingroup g_feature
39  @brief internal class for feature passing only
40  @author koeser 09/2004
41  */
42  class BIASFeatureDetector_EXPORT Feat {
43  public:
44  int x, y;
45  double val;
46 
47  bool operator<(const Feat& r) const
48  { return val>r.val; }
49 
50  Feat& operator=(const Feat& f)
51  { x=f.x; y=f.y; val=f.val; return *this; }
52 
53  }; // end of class Feat
54 /** \endcond */
55 
56  inline std::ostream& operator<<(std::ostream & os, const Feat& f)
57  { os << "("<<f.x<<", "<<f.y<<") = "<<f.val; return os; }
58 
59 
60 
61  /** @class CornerDetectorGradient
62  @ingroup g_feature
63  @brief base class for all gradient based corner detectors
64 
65  provides functionality to compute the structure tensor
66  | gxx gxy |
67  | gyx gyy |
68 
69  The function detect low pass filters the image, computes gradients and
70  the structure tensor and then calls _ComputeCornerness on the structure
71  tensor image. This function must be implemented in derived classes, it
72  basically converts the 2x2 structure tensor to a scalar value which
73  describes how much cornerlike the region around that pixel is, which
74  is saved in the cornerness image. Values above a threshold are pushed
75  into an internal list.
76  Afterwards the EnforceMinimumDistance function is called to sort features
77  by quality and add them to the final list. New points are accepted only
78  if the have a minimum distance to all previously extracted points.
79  In the detect function you may pass a non-empty vector of points,
80  which are regarded as "existing corners" and none of the new points may
81  lie withing the critical distance around the old ones. This gives the
82  possibility to detect new features for a tracker, which has tracked
83  some points (where no new features are desired) and lost some features.
84 
85  @author woelk/koeser 09/2004 */
86  template <class StorageType, class CalculationType>
87  class BIASFeatureDetector_EXPORT CornerDetectorGradient :
88  public CornerDetectorBase<StorageType>
89  {
90  public:
92  virtual ~CornerDetectorGradient();
93 
94  /** @brief detect corners in a grey image
95 
96  see documentation of BIAS::CornerDetectorGradient class for more info
97  @param image grey value input image
98  @param p all points in p _not_ lying at infinity (p[i][2]!=0) are
99  assumed to be corners of very good quality, in the region around these
100  points no new features are detected, leave empty if you just want
101  to detect some features in the image
102  In any case p is cleared and only new detected points are added before
103  returning. Example: assume MaxNum=100, you pass a vector p with 40
104  points of which 12 have the third coordinate w=0. You will get back a
105  vector of maximum size 72, it may be smaller if Distance and
106  MinCornerness have too large values
107  @param quality after returning, for each point in p there is a
108  quality in quality, no input requirements */
109  virtual int Detect(const Image<StorageType>& image,
110  std::vector<HomgPoint2D>& p,
111  std::vector<QUAL>& quality,
112  std::vector<Matrix2x2<double> > *cov = NULL);
113 
114  /** @brief detect corners given the gradient images
115 
116  see documentation of BIAS::CornerDetectorGradient class for more info
117  @param gradx image containing gradient x component
118  @param grady image containing gradient y component
119  @param p all points in p _not_ lying at infinity (p[i][2]!=0) are
120  assumed to be corners of very good quality, in the region around these
121  points no new features are detected, leave empty if you just want
122  to detect some features in the image.
123  In any case p is cleared and only new detected points are added before
124  returning. Example: assume MaxNum=100, you pass a vector p with 40
125  points of which 12 have the third coordinate w=0. You will get back a
126  vector of maximum size 72, it may be smaller if Distance and
127  MinCornerness have too large values
128  @param quality after returning, for each point in p there is a
129  quality in quality, no input requirements */
130  virtual int Detect(const Image<CalculationType>& gradx,
131  const Image<CalculationType>& grady,
132  std::vector<HomgPoint2D>& p,
133  std::vector<QUAL>& quality,
134  std::vector<Matrix2x2<double> > *cov = NULL);
135 
136 
137  /** @brief detect corners avoiding double calculation of cornerness image
138 
139  see documentation of BIAS::CornerDetectorGradient class for more info
140  @param cornerness image with already computed cornerness
141  @param p all points in p _not_ lying at infinity (p[i][2]!=0) are
142  assumed to be corners of very good quality, in the region around these
143  points no new features are detected, leave empty if you just want
144  to detect some features in the image
145  In any case p is cleared and only new detected points are added before
146  returning. Example: assume MaxNum=100, you pass a vector p with 40
147  points of which 12 have the third coordinate w=0. You will get back a
148  vector of maximum size 72, it may be smaller if Distance and
149  MinCornerness have too large values
150  @param quality after returning, for each point in p there is a
151  quality in quality, no input requirements */
152  virtual int DetectFromCornerness(const Image<CalculationType>& cornerness,
153  std::vector<HomgPoint2D>& p,
154  std::vector<QUAL>& quality);
155 
156 
157  /** @brief detect corners avoiding double calculation of cornerness image
158  @author Dennis Herzog, June 2005 */
159  virtual int DetectFromCornerness(const Image<CalculationType> &cornerness,
160  const std::vector<Vector2<int> > &region,
161  std::vector<HomgPoint2D> &p,
162  std::vector<QUAL> &quality);
163 
164  /** @brief calculates the cornerness using the gradients gx and gy
165  @author woelk 09/2004 */
166  virtual int Cornerness(const Image<CalculationType>& gradx,
167  const Image<CalculationType>& grady,
168  Image<CalculationType>& cornerness);
169 
170 
171  /** @brief rets the min distance of features
172  (simple parameter access function - does nothing else)
173  @author Dennis Herzog, 2005-06-22 */
174  inline int GetMinDistance() const
175  { return _MinDistance; }
176 
177  /** @brief sets the min distance of features
178  (simple parameter access function - does nothing else)
179  @author Dennis Herzog, 2005-06-22 */
180  inline void SetMinDistance(int mindist)
181  { _MinDistance = mindist; }
182 
183  /** @brief rets minimum cornernes of detectable features
184  (simple parameter access function - does nothing else)
185  @author Dennis Herzog, 2005-07-04 */
186  inline double GetMinCornerness()
187  { return _MinCornerness; }
188 
189  /** @brief sets minimum cornernes of detectable features
190  @author woelk 02/2006 */
191  virtual inline void SetMinCornerness(double min_cornerness)
192  { _MinCornerness = min_cornerness; }
193 
194  /** @author woelk 02/2006 */
195  inline void SetSubpixelAccuracy(bool subpixel_accuracy)
196  { _DoRefinement = subpixel_accuracy; }
197 
198  virtual inline void SetStructureTensorHalfWinSize(int halfwinsize)
199  { _st.SetHalfWinSize(halfwinsize); }
200 
201  virtual inline const Image<CalculationType>& GetCornernessImage() const
202  { return _Cornerness; }
203 
204  protected:
205 
206  // exports for dll (cmenk)
207  //BIAS_EXPORT_STL_VECTOR( BIASFeatureDetector_EXPORT, class Feat )
208 
209  /** calculates the cornerness using the src image
210  @author woelk 09/2004 */
211  int _CalcCornerness(const Image<StorageType>& src,
212  Image<CalculationType>& cornerness);
213 
214  /** calculates the cornerness using the gradients gx and gy
215  @author woelk 09/2004 */
216  int _CalcCornerness(const Image<CalculationType>& gradx,
217  const Image<CalculationType>& grady,
218  Image<CalculationType>& cornerness);
219 
220  /** @brief the main function which should be overwritten in derived
221  classes, no implementation in this class
222 
223  computes the cornerness from the structure tensor image
224  Uses structure tensor sgxx, _sgxy, _sgyy as input */
225  virtual int _ComputeCornerness(Image<CalculationType>& Cornerness);
226 
227  /** @brief extracts the local maxima checking a 3x3 region
228  into _FeatList */
229  void _ExtractLocalMaxima(const Image<CalculationType>& Cornerness);
230 
231  /** @brief selects features sorted by quality from _FeatList such that they
232  have a min distance as given in the param object
233 
234  assumes feature map is zeroed
235  @author woelk 09/2004 */
236  int _EnforceMinimumDistance(std::vector<HomgPoint2D>& p,
237  std::vector<QUAL>& quality);
238 
239  /** @brief fit quadratic surface around (row;col) to find the maximum
240  cornerness subpixel position and save it in x;y
241  @param col column in image where refinement should take place
242  @param row row in image where refinement should take place
243  @param x output, refined coordinate
244  @param y output, refined coordinate
245  @param SubPixelCornerness cornerness value at subpixel maximum
246  @author koeser 01/2004 */
247  bool _RefineCornerPosition(int col, int row,
248  double &x, double &y, QUAL &SubPixelCornerness);
249 
250  /** @brief refines corner position and quality for all corners in list,
251  internal Cornerness_ image must be valid
252  @param pos input/output of old/new position
253  @param quality holds new cornernesses afterwards
254  @author koeser 09/2004 */
255  inline void _RefineCorners(std::vector<HomgPoint2D>& pos,
256  std::vector<QUAL>& quality) {
257  BIASASSERT(pos.size()==quality.size());
258  std::vector<QUAL>::iterator itq = quality.begin();
259  for (std::vector<HomgPoint2D>::iterator itp=pos.begin();
260  itp!=pos.end(); itp++, itq++)
261  _RefineCornerPosition((int)rint((*itp)[0]), (int)rint((*itp)[1]),
262  (*itp)[0], (*itp)[1], *itq);
263  }
264 
265  /// @brief frees _Cornerness, _sgxx, _sgxy and _sgyy
266  void _DeleteInternalMem();
267 
268  /// @brief allocates _Cornerness , _sgxx, _sgxy and _sgyy
269  void _AllocInternalMem(const int width, const int height);
270 
271  /// @brief zeros the feature map
272  inline void _ZeroFeatureMap()
273  { memset((void*)_FeatureMap[0], 0,
274  sizeof(bool)*_Cornerness.GetWidth()*_Cornerness.GetHeight());
275  _NumberFeaturesSoFar = 0;};
276 
277  /// @brief fills feature map with every point from p which isnt at infinity
278  void _FillFeatureMap(std::vector<HomgPoint2D>& p);
279 
280  /** @brief returns the inverse structure tensor, multiplied by noise^2
281  @author woelk 03/2006 */
282  void GetCov_(const std::vector<HomgPoint2D>& p,
283  std::vector<Matrix2x2<double> >& cov,
284  const double noise = 5) const;
285 
286  /// structure tensor computation object
288 
289  /// internal structure tensor images
291 
292  /// resulting image which tells for each pixel how cornerlike it is
294 
295  /// array used to enforce a min distance / neighbor suppression
296  bool **_FeatureMap;
297 
298  /// temporary list of detected corners
299  std::vector<class Feat> _FeatList;
300 
301  /// Gauss for pre-smoothing
303 
304  /// initialized with the old features provided by user, then counted up
305  /// and compared against _MaxNumFeatures from Base class
307 
308  // parameter
309  int _MinDistance; ///< minimal distance between points
310  double _MinCornerness; ///< threshold to accept a feature
311  bool _DoRefinement; ///< tells whether subpixel refinement should be done
312  }; // class
313 
314 } // namespace
315 
316 #ifndef __APPLE__
317 // DLL JW
318 namespace std {
319  template class BIASFeatureDetector_EXPORT std::vector<class BIAS::Feat>;
320 }
321 #endif
322 
323 #endif // __CornerDetectorGradient_hh__
void SetMinDistance(int mindist)
sets the min distance of features (simple parameter access function - does nothing else) ...
int _MinDistance
minimal distance between points
void SetSubpixelAccuracy(bool subpixel_accuracy)
int GetMinDistance() const
rets the min distance of features (simple parameter access function - does nothing else) ...
Image< CalculationType > _Cornerness
resulting image which tells for each pixel how cornerlike it is
virtual const Image< CalculationType > & GetCornernessImage() const
bool _DoRefinement
tells whether subpixel refinement should be done
virtual void SetStructureTensorHalfWinSize(int halfwinsize)
double GetMinCornerness()
rets minimum cornernes of detectable features (simple parameter access function - does nothing else) ...
double _MinCornerness
threshold to accept a feature
virtual void SetMinCornerness(double min_cornerness)
sets minimum cornernes of detectable features
bool ** _FeatureMap
array used to enforce a min distance / neighbor suppression
std::vector< class Feat > _FeatList
temporary list of detected corners
void _ZeroFeatureMap()
zeros the feature map
The image template class for specific storage types.
Definition: Image.hh:78
Gauss< StorageType, StorageType > _gauss
Gauss for pre-smoothing.
bool operator<(const BIAS::Polynom &p1, const BIAS::Polynom &p2)
Definition: Polynom.hh:293
std::ostream & operator<<(std::ostream &os, const Array2D< T > &arg)
Definition: Array2D.hh:260
void _RefineCorners(std::vector< HomgPoint2D > &pos, std::vector< QUAL > &quality)
refines corner position and quality for all corners in list, internal Cornerness_ image must be valid...
int _NumberFeaturesSoFar
initialized with the old features provided by user, then counted up and compared against _MaxNumFeatu...
StructureTensor< CalculationType, CalculationType > _st
structure tensor computation object
purly virtual interface defining class for corner detectors
base class for all gradient based corner detectors