Merge remote-tracking branch 'origin/2.4' into merge-2.4
[platform/upstream/opencv.git] / samples / gpu / generalized_hough.cpp
1 #include <vector>
2 #include <iostream>
3 #include <string>
4
5 #include "opencv2/core.hpp"
6 #include "opencv2/core/utility.hpp"
7 #include "opencv2/imgproc.hpp"
8 #include "opencv2/cudaimgproc.hpp"
9 #include "opencv2/highgui.hpp"
10 #include "opencv2/contrib.hpp"
11
12 using namespace std;
13 using namespace cv;
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         "{ full           |           | estimate scale and rotation }"
32         "{ gpu            |           | use gpu version }"
33         "{ minDist        | 100       | minimum distance between the centers of the detected objects }"
34         "{ levels         | 360       | R-Table levels }"
35         "{ votesThreshold | 30        | the accumulator threshold for the template centers at the detection stage. The smaller it is, the more false positions may be detected }"
36         "{ angleThresh    | 10000     | angle votes treshold }"
37         "{ scaleThresh    | 1000      | scale votes treshold }"
38         "{ posThresh      | 100       | position votes threshold }"
39         "{ dp             | 2         | inverse ratio of the accumulator resolution to the image resolution }"
40         "{ minScale       | 0.5       | minimal scale to detect }"
41         "{ maxScale       | 2         | maximal scale to detect }"
42         "{ scaleStep      | 0.05      | scale step }"
43         "{ minAngle       | 0         | minimal rotation angle to detect in degrees }"
44         "{ maxAngle       | 360       | maximal rotation angle to detect in degrees }"
45         "{ angleStep      | 1         | angle step in degrees }"
46         "{ maxBufSize     | 1000      | maximal size of inner buffers }"
47         "{ help h ?       |           | print help message }"
48     );
49
50     cmd.about("This program demonstrates arbitary object finding with the Generalized Hough transform.");
51
52     if (cmd.has("help"))
53     {
54         cmd.printMessage();
55         return 0;
56     }
57
58     const string templName = cmd.get<string>("template");
59     const string imageName = cmd.get<string>("image");
60     const bool full = cmd.has("full");
61     const bool useGpu = cmd.has("gpu");
62     const double minDist = cmd.get<double>("minDist");
63     const int levels = cmd.get<int>("levels");
64     const int votesThreshold = cmd.get<int>("votesThreshold");
65     const int angleThresh = cmd.get<int>("angleThresh");
66     const int scaleThresh = cmd.get<int>("scaleThresh");
67     const int posThresh = cmd.get<int>("posThresh");
68     const double dp = cmd.get<double>("dp");
69     const double minScale = cmd.get<double>("minScale");
70     const double maxScale = cmd.get<double>("maxScale");
71     const double scaleStep = cmd.get<double>("scaleStep");
72     const double minAngle = cmd.get<double>("minAngle");
73     const double maxAngle = cmd.get<double>("maxAngle");
74     const double angleStep = cmd.get<double>("angleStep");
75     const int maxBufSize = cmd.get<int>("maxBufSize");
76
77     if (!cmd.check())
78     {
79         cmd.printErrors();
80         return -1;
81     }
82
83     Mat templ = loadImage(templName);
84     Mat image = loadImage(imageName);
85
86     Ptr<GeneralizedHough> alg;
87
88     if (!full)
89     {
90         Ptr<GeneralizedHoughBallard> ballard = useGpu ? cuda::createGeneralizedHoughBallard() : createGeneralizedHoughBallard();
91
92         ballard->setMinDist(minDist);
93         ballard->setLevels(levels);
94         ballard->setDp(dp);
95         ballard->setMaxBufferSize(maxBufSize);
96         ballard->setVotesThreshold(votesThreshold);
97
98         alg = ballard;
99     }
100     else
101     {
102         Ptr<GeneralizedHoughGuil> guil = useGpu ? cuda::createGeneralizedHoughGuil() : createGeneralizedHoughGuil();
103
104         guil->setMinDist(minDist);
105         guil->setLevels(levels);
106         guil->setDp(dp);
107         guil->setMaxBufferSize(maxBufSize);
108
109         guil->setMinAngle(minAngle);
110         guil->setMaxAngle(maxAngle);
111         guil->setAngleStep(angleStep);
112         guil->setAngleThresh(angleThresh);
113
114         guil->setMinScale(minScale);
115         guil->setMaxScale(maxScale);
116         guil->setScaleStep(scaleStep);
117         guil->setScaleThresh(scaleThresh);
118
119         guil->setPosThresh(posThresh);
120
121         alg = guil;
122     }
123
124     vector<Vec4f> position;
125     TickMeter tm;
126
127     if (useGpu)
128     {
129         cuda::GpuMat d_templ(templ);
130         cuda::GpuMat d_image(image);
131         cuda::GpuMat d_position;
132
133         alg->setTemplate(d_templ);
134
135         tm.start();
136
137         alg->detect(d_image, d_position);
138         d_position.download(position);
139
140         tm.stop();
141     }
142     else
143     {
144         alg->setTemplate(templ);
145
146         tm.start();
147
148         alg->detect(image, position);
149
150         tm.stop();
151     }
152
153     cout << "Found : " << position.size() << " objects" << endl;
154     cout << "Detection time : " << tm.getTimeMilli() << " ms" << endl;
155
156     Mat out;
157     cv::cvtColor(image, out, COLOR_GRAY2BGR);
158
159     for (size_t i = 0; i < position.size(); ++i)
160     {
161         Point2f pos(position[i][0], position[i][1]);
162         float scale = position[i][2];
163         float angle = position[i][3];
164
165         RotatedRect rect;
166         rect.center = pos;
167         rect.size = Size2f(templ.cols * scale, templ.rows * scale);
168         rect.angle = angle;
169
170         Point2f pts[4];
171         rect.points(pts);
172
173         line(out, pts[0], pts[1], Scalar(0, 0, 255), 3);
174         line(out, pts[1], pts[2], Scalar(0, 0, 255), 3);
175         line(out, pts[2], pts[3], Scalar(0, 0, 255), 3);
176         line(out, pts[3], pts[0], Scalar(0, 0, 255), 3);
177     }
178
179     imshow("out", out);
180     waitKey();
181
182     return 0;
183 }