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 5 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 MORPHOF
19
#define MORPHOF
20
 
21
#include <opencv2/core/core.hpp>
22
#include <opencv2/imgproc/imgproc.hpp>
23
 
24
class MorphoFeatures {
25
 
26
  private:
27
 
28
          // threshold to produce binary image
29
          int threshold;
30
          // structuring elements used in corner detection
31
          cv::Mat cross;
32
          cv::Mat diamond;
33
          cv::Mat square;
34
          cv::Mat x;
35
 
36
          void applyThreshold(cv::Mat& result) {
37
 
38
          // Apply threshold on result
39
                  if (threshold>0)
40
                        cv::threshold(result, result, threshold, 255, cv::THRESH_BINARY_INV);
41
          }
42
 
43
  public:
44
 
45
          MorphoFeatures() : threshold(-1), cross(5,5,CV_8U,cv::Scalar(0)),
46
                                                diamond(5,5,CV_8U,cv::Scalar(1)),
47
                                                                                square(5,5,CV_8U,cv::Scalar(1)),
48
                                                                                x(5,5,CV_8U,cv::Scalar(0)){
49
 
50
                  // Creating the cross-shaped structuring element
51
                  for (int i=0; i<5; i++) {
52
 
53
                          cross.at<uchar>(2,i)= 1;
54
                          cross.at<uchar>(i,2)= 1;                                                                     
55
                  }
56
 
57
                  // Creating the diamond-shaped structuring element
58
                  diamond.at<uchar>(0,0)= 0;
59
                  diamond.at<uchar>(0,1)= 0;
60
                  diamond.at<uchar>(1,0)= 0;
61
                  diamond.at<uchar>(4,4)= 0;
62
                  diamond.at<uchar>(3,4)= 0;
63
                  diamond.at<uchar>(4,3)= 0;
64
                  diamond.at<uchar>(4,0)= 0;
65
                  diamond.at<uchar>(4,1)= 0;
66
                  diamond.at<uchar>(3,0)= 0;
67
                  diamond.at<uchar>(0,4)= 0;
68
                  diamond.at<uchar>(0,3)= 0;
69
                  diamond.at<uchar>(1,4)= 0;
70
 
71
                  // Creating the x-shaped structuring element
72
                  for (int i=0; i<5; i++) {
73
 
74
                          x.at<uchar>(i,i)= 1;
75
                          x.at<uchar>(4-i,i)= 1;                                                                       
76
                  }
77
          }
78
 
79
          void setThreshold(int t) {
80
 
81
                  threshold= t;
82
          }
83
 
84
          int getThreshold() const {
85
 
86
                  return threshold;
87
          }
88
 
89
          cv::Mat getEdges(const cv::Mat &image) {
90
 
91
                  // Get the gradient image
92
                  cv::Mat result;
93
                  cv::morphologyEx(image,result,cv::MORPH_GRADIENT,cv::Mat());
94
 
95
          // Apply threshold to obtain a binary image
96
                  applyThreshold(result);
97
 
98
                  return result;
99
          }
100
 
101
          cv::Mat getCorners(const cv::Mat &image) {
102
 
103
                  cv::Mat result;
104
 
105
                  // Dilate with a cross        
106
                  cv::dilate(image,result,cross);
107
 
108
                  // Erode with a diamond
109
                  cv::erode(result,result,diamond);
110
 
111
                  cv::Mat result2;
112
                  // Dilate with a X    
113
                  cv::dilate(image,result2,x);
114
 
115
                  // Erode with a square
116
                  cv::erode(result2,result2,square);
117
 
118
                  // Corners are obtained by differencing
119
                  // the two closed images
120
                  cv::absdiff(result2,result,result);
121
 
122
          // Apply threshold to obtain a binary image
123
                  applyThreshold(result);
124
 
125
                  return result;
126
          }
127
 
128
          void drawOnImage(const cv::Mat& binary, cv::Mat& image) {
129
 
130
                  cv::Mat_<uchar>::const_iterator it= binary.begin<uchar>();
131
                  cv::Mat_<uchar>::const_iterator itend= binary.end<uchar>();
132
 
133
                  // for each pixel     
134
                  for (int i=0; it!= itend; ++it,++i) {
135
                          if (!*it)
136
                                  cv::circle(image,cv::Point(i%image.step,i/image.step),5,cv::Scalar(255,0,0));
137
                  }
138
          }
139
};
140
 
141
 
142
#endif