added Generalized Hough implementation
[profile/ivi/opencv.git] / samples / cpp / generalized_hough.cpp
1 #include <vector>
2 #include <iostream>
3 #include <string>
4
5 #include "opencv2/core/core.hpp"
6 #include "opencv2/imgproc/imgproc.hpp"
7 #include "opencv2/gpu/gpu.hpp"
8 #include "opencv2/highgui/highgui.hpp"
9 #include "opencv2/contrib/contrib.hpp"
10
11 using namespace std;
12 using namespace cv;
13 using namespace cv::gpu;
14
15 static Mat loadImage(const string& name)
16 {
17     Mat image = imread(name, IMREAD_GRAYSCALE);
18     if (image.empty())
19     {
20         cerr << "Can't load image - " << name << endl;
21         exit(-1);
22     }
23     return image;
24 }
25
26 int main(int argc, const char* argv[])
27 {
28     CommandLineParser cmd(argc, argv,
29         "{ image i        | pic1.png  | input image }"
30         "{ template t     | templ.png | template image }"
31         "{ scale s        |           | estimate scale }"
32         "{ rotation r     |           | estimate rotation }"
33         "{ gpu            |           | use gpu version }"
34         "{ minDist        | 100       | minimum distance between the centers of the detected objects }"
35         "{ levels         | 360       | R-Table levels }"
36         "{ votesThreshold | 30        | the accumulator threshold for the template centers at the detection stage. The smaller it is, the more false positions may be detected }"
37         "{ angleThresh    | 10000     | angle votes treshold }"
38         "{ scaleThresh    | 1000      | scale votes treshold }"
39         "{ posThresh      | 100       | position votes threshold }"
40         "{ dp             | 2         | inverse ratio of the accumulator resolution to the image resolution }"
41         "{ minScale       | 0.5       | minimal scale to detect }"
42         "{ maxScale       | 2         | maximal scale to detect }"
43         "{ scaleStep      | 0.05      | scale step }"
44         "{ minAngle       | 0         | minimal rotation angle to detect in degrees }"
45         "{ maxAngle       | 360       | maximal rotation angle to detect in degrees }"
46         "{ angleStep      | 1         | angle step in degrees }"
47         "{ maxSize        | 1000      | maximal size of inner buffers }"
48         "{ help h ?       |           | print help message }"
49     );
50
51     cmd.about("This program demonstrates arbitary object finding with the Generalized Hough transform.");
52
53     if (cmd.has("help"))
54     {
55         cmd.printMessage();
56         return 0;
57     }
58
59     const string templName = cmd.get<string>("template");
60     const string imageName = cmd.get<string>("image");
61     const bool estimateScale = cmd.has("scale");
62     const bool estimateRotation = cmd.has("rotation");
63     const bool useGpu = cmd.has("gpu");
64     const double minDist = cmd.get<double>("minDist");
65     const int levels = cmd.get<int>("levels");
66     const int votesThreshold = cmd.get<int>("votesThreshold");
67     const int angleThresh = cmd.get<int>("angleThresh");
68     const int scaleThresh = cmd.get<int>("scaleThresh");
69     const int posThresh = cmd.get<int>("posThresh");
70     const double dp = cmd.get<double>("dp");
71     const double minScale = cmd.get<double>("minScale");
72     const double maxScale = cmd.get<double>("maxScale");
73     const double scaleStep = cmd.get<double>("scaleStep");
74     const double minAngle = cmd.get<double>("minAngle");
75     const double maxAngle = cmd.get<double>("maxAngle");
76     const double angleStep = cmd.get<double>("angleStep");
77     const int maxSize = cmd.get<int>("maxSize");
78
79     if (!cmd.check())
80     {
81         cmd.printErrors();
82         return -1;
83     }
84
85     Mat templ = loadImage(templName);
86     Mat image = loadImage(imageName);
87
88     int method = GHT_POSITION;
89     if (estimateScale)
90         method += GHT_SCALE;
91     if (estimateRotation)
92         method += GHT_ROTATION;
93
94     vector<Vec4f> position;
95     cv::TickMeter tm;
96
97     if (useGpu)
98     {
99         GpuMat d_templ(templ);
100         GpuMat d_image(image);
101         GpuMat d_position;
102
103         Ptr<GeneralizedHough_GPU> d_hough = GeneralizedHough_GPU::create(method);
104         d_hough->set("minDist", minDist);
105         d_hough->set("levels", levels);
106         d_hough->set("dp", dp);
107         d_hough->set("maxSize", maxSize);
108         if (estimateScale && estimateRotation)
109         {
110             d_hough->set("angleThresh", angleThresh);
111             d_hough->set("scaleThresh", scaleThresh);
112             d_hough->set("posThresh", posThresh);
113         }
114         else
115         {
116             d_hough->set("votesThreshold", votesThreshold);
117         }
118         if (estimateScale)
119         {
120             d_hough->set("minScale", minScale);
121             d_hough->set("maxScale", maxScale);
122             d_hough->set("scaleStep", scaleStep);
123         }
124         if (estimateRotation)
125         {
126             d_hough->set("minAngle", minAngle);
127             d_hough->set("maxAngle", maxAngle);
128             d_hough->set("angleStep", angleStep);
129         }
130
131         d_hough->setTemplate(d_templ);
132
133         tm.start();
134
135         d_hough->detect(d_image, d_position);
136         d_hough->download(d_position, position);
137
138         tm.stop();
139     }
140     else
141     {
142         Ptr<GeneralizedHough> hough = GeneralizedHough::create(method);
143         hough->set("minDist", minDist);
144         hough->set("levels", levels);
145         hough->set("dp", dp);
146         if (estimateScale && estimateRotation)
147         {
148             hough->set("angleThresh", angleThresh);
149             hough->set("scaleThresh", scaleThresh);
150             hough->set("posThresh", posThresh);
151             hough->set("maxSize", maxSize);
152         }
153         else
154         {
155             hough->set("votesThreshold", votesThreshold);
156         }
157         if (estimateScale)
158         {
159             hough->set("minScale", minScale);
160             hough->set("maxScale", maxScale);
161             hough->set("scaleStep", scaleStep);
162         }
163         if (estimateRotation)
164         {
165             hough->set("minAngle", minAngle);
166             hough->set("maxAngle", maxAngle);
167             hough->set("angleStep", angleStep);
168         }
169
170         hough->setTemplate(templ);
171
172         tm.start();
173
174         hough->detect(image, position);
175
176         tm.stop();
177     }
178
179     cout << "Found : " << position.size() << " objects" << endl;
180     cout << "Detection time : " << tm.getTimeMilli() << " ms" << endl;
181
182     Mat out;
183     cvtColor(image, out, COLOR_GRAY2BGR);
184
185     for (size_t i = 0; i < position.size(); ++i)
186     {
187         Point2f pos(position[i][0], position[i][1]);
188         float scale = position[i][2];
189         float angle = position[i][3];
190
191         RotatedRect rect;
192         rect.center = pos;
193         rect.size = Size2f(templ.cols * scale, templ.rows * scale);
194         rect.angle = angle;
195
196         Point2f pts[4];
197         rect.points(pts);
198
199         line(out, pts[0], pts[1], Scalar(0, 0, 255), 3);
200         line(out, pts[1], pts[2], Scalar(0, 0, 255), 3);
201         line(out, pts[2], pts[3], Scalar(0, 0, 255), 3);
202         line(out, pts[3], pts[0], Scalar(0, 0, 255), 3);
203     }
204
205     imshow("out", out);
206     waitKey();
207
208     return 0;
209 }