Subversion Repositories OpenCV2-Cookbook

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 PointedEar 1
/*------------------------------------------------------------------------------------------*\
2
   This file contains material supporting chapter 8 of the cookbook:  
3
   Computer Vision Programming using the OpenCV Library.
4
   by Robert Laganiere, Packt Publishing, 2011.
5
 
6
   This program is free software; permission is hereby granted to use, copy, modify,
7
   and distribute this source code, or portions thereof, for any purpose, without fee,
8
   subject to the restriction that the copyright notice may not be removed
9
   or altered from any source or altered source distribution.
10
   The software is released on an as-is basis and without any warranties of any kind.
11
   In particular, the software is not guaranteed to be fault-tolerant or free from failure.
12
   The author disclaims all warranties with regard to this software, any use,
13
   and any consequent failure, is purely the responsibility of the user.
14
 
15
   Copyright (C) 2010-2011 Robert Laganiere, www.laganiere.name
16
\*------------------------------------------------------------------------------------------*/
17
 
18
#if !defined HARRISD
19
#define HARRISD
20
 
21
#include <vector>
22
#include <opencv2/core/core.hpp>
23
#include <opencv2/imgproc/imgproc.hpp>
24
#include <opencv2/highgui/highgui.hpp>
25
#include <opencv2/features2d/features2d.hpp>
26
 
27
class HarrisDetector {
28
 
29
  private:
30
 
31
          // 32-bit float image of corner strength
32
          cv::Mat cornerStrength;
33
          // 32-bit float image of thresholded corners
34
          cv::Mat cornerTh;
35
          // image of local maxima (internal)
36
          cv::Mat localMax;
37
          // size of neighbourhood for derivatives smoothing
38
          int neighbourhood;
39
          // aperture for gradient computation
40
          int aperture;
41
          // Harris parameter
42
          double k;
43
          // maximum strength for threshold computation
44
          double maxStrength;
45
          // calculated threshold (internal)
46
          double threshold;
47
          // size of neighbourhood for non-max suppression
48
          int nonMaxSize;
49
          // kernel for non-max suppression
50
          cv::Mat kernel;
51
 
52
  public:
53
 
54
          HarrisDetector() : neighbourhood(3), aperture(3), k(0.1), maxStrength(0.0), threshold(0.01), nonMaxSize(3) {
55
 
56
                  setLocalMaxWindowSize(nonMaxSize);
57
          }
58
 
59
          // Create kernel used in non-maxima suppression
60
          void setLocalMaxWindowSize(int size) {
61
 
62
                  nonMaxSize= size;
63
                  kernel.create(nonMaxSize,nonMaxSize,CV_8U);
64
          }
65
 
66
          // Compute Harris corners
67
          void detect(const cv::Mat& image) {
68
 
69
                  // Harris computation
70
                  cv::cornerHarris(image,cornerStrength,
71
                             neighbourhood,// neighborhood size
72
                                         aperture,     // aperture size
73
                                         k);           // Harris parameter
74
 
75
                  // internal threshold computation
76
                  double minStrength; // not used
77
                  cv::minMaxLoc(cornerStrength,&minStrength,&maxStrength);
78
 
79
                  // local maxima detection
80
                  cv::Mat dilated;  // temporary image
81
                  cv::dilate(cornerStrength,dilated,cv::Mat());
82
                  cv::compare(cornerStrength,dilated,localMax,cv::CMP_EQ);
83
          }
84
 
85
          // Get the corner map from the computed Harris values
86
          cv::Mat getCornerMap(double qualityLevel) {
87
 
88
                  cv::Mat cornerMap;
89
 
90
                  // thresholding the corner strength
91
                  threshold= qualityLevel*maxStrength;
92
                  cv::threshold(cornerStrength,cornerTh,threshold,255,cv::THRESH_BINARY);
93
 
94
                  // convert to 8-bit image
95
                  cornerTh.convertTo(cornerMap,CV_8U);
96
 
97
                  // non-maxima suppression
98
                  cv::bitwise_and(cornerMap,localMax,cornerMap);
99
 
100
                  return cornerMap;
101
          }
102
 
103
          // Get the feature points vector from the computed Harris values
104
          void getCorners(std::vector<cv::Point> &points, double qualityLevel) {
105
 
106
                  // Get the corner map
107
                  cv::Mat cornerMap= getCornerMap(qualityLevel);
108
                  // Get the corners
109
                  getCorners(points, cornerMap);
110
          }
111
 
112
          // Get the feature points vector from the computed corner map
113
          void getCorners(std::vector<cv::Point> &points, const cv::Mat& cornerMap) {
114
 
115
                  // Iterate over the pixels to obtain all feature points
116
                  for( int y = 0; y < cornerMap.rows; y++ ) {
117
 
118
                          const uchar* rowPtr = cornerMap.ptr<uchar>(y);
119
 
120
                          for( int x = 0; x < cornerMap.cols; x++ ) {
121
 
122
                                  // if it is a feature point
123
                                  if (rowPtr[x]) {
124
 
125
                                          points.push_back(cv::Point(x,y));
126
                                  }
127
                          }
128
                  }
129
          }
130
 
131
          // Draw circles at feature point locations on an image
132
          void drawOnImage(cv::Mat &image, const std::vector<cv::Point> &points, cv::Scalar color= cv::Scalar(255,255,255), int radius=3, int thickness=2) {
133
 
134
                  std::vector<cv::Point>::const_iterator it= points.begin();
135
 
136
                  // for all corners
137
                  while (it!=points.end()) {
138
 
139
                          // draw a circle at each corner location
140
                          cv::circle(image,*it,radius,color,thickness);
141
                          ++it;
142
                  }
143
          }
144
};
145
 
146
#endif