Merge pull request #3184 from ilya-lavrenov:arm
[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
11 #include "tick_meter.hpp"
12
13 using namespace std;
14 using namespace cv;
15
16 static Mat loadImage(const string& name)
17 {
18     Mat image = imread(name, IMREAD_GRAYSCALE);
19     if (image.empty())
20     {
21         cerr << "Can't load image - " << name << endl;
22         exit(-1);
23     }
24     return image;
25 }
26
27 int main(int argc, const char* argv[])
28 {
29     CommandLineParser cmd(argc, argv,
30         "{ image i        | pic1.png  | input image }"
31         "{ template t     | templ.png | template image }"
32         "{ full           |           | estimate scale and 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         "{ maxBufSize     | 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 full = cmd.has("full");
62     const bool useGpu = cmd.has("gpu");
63     const double minDist = cmd.get<double>("minDist");
64     const int levels = cmd.get<int>("levels");
65     const int votesThreshold = cmd.get<int>("votesThreshold");
66     const int angleThresh = cmd.get<int>("angleThresh");
67     const int scaleThresh = cmd.get<int>("scaleThresh");
68     const int posThresh = cmd.get<int>("posThresh");
69     const double dp = cmd.get<double>("dp");
70     const double minScale = cmd.get<double>("minScale");
71     const double maxScale = cmd.get<double>("maxScale");
72     const double scaleStep = cmd.get<double>("scaleStep");
73     const double minAngle = cmd.get<double>("minAngle");
74     const double maxAngle = cmd.get<double>("maxAngle");
75     const double angleStep = cmd.get<double>("angleStep");
76     const int maxBufSize = cmd.get<int>("maxBufSize");
77
78     if (!cmd.check())
79     {
80         cmd.printErrors();
81         return -1;
82     }
83
84     Mat templ = loadImage(templName);
85     Mat image = loadImage(imageName);
86
87     Ptr<GeneralizedHough> alg;
88
89     if (!full)
90     {
91         Ptr<GeneralizedHoughBallard> ballard = useGpu ? cuda::createGeneralizedHoughBallard() : createGeneralizedHoughBallard();
92
93         ballard->setMinDist(minDist);
94         ballard->setLevels(levels);
95         ballard->setDp(dp);
96         ballard->setMaxBufferSize(maxBufSize);
97         ballard->setVotesThreshold(votesThreshold);
98
99         alg = ballard;
100     }
101     else
102     {
103         Ptr<GeneralizedHoughGuil> guil = useGpu ? cuda::createGeneralizedHoughGuil() : createGeneralizedHoughGuil();
104
105         guil->setMinDist(minDist);
106         guil->setLevels(levels);
107         guil->setDp(dp);
108         guil->setMaxBufferSize(maxBufSize);
109
110         guil->setMinAngle(minAngle);
111         guil->setMaxAngle(maxAngle);
112         guil->setAngleStep(angleStep);
113         guil->setAngleThresh(angleThresh);
114
115         guil->setMinScale(minScale);
116         guil->setMaxScale(maxScale);
117         guil->setScaleStep(scaleStep);
118         guil->setScaleThresh(scaleThresh);
119
120         guil->setPosThresh(posThresh);
121
122         alg = guil;
123     }
124
125     vector<Vec4f> position;
126     TickMeter tm;
127
128     if (useGpu)
129     {
130         cuda::GpuMat d_templ(templ);
131         cuda::GpuMat d_image(image);
132         cuda::GpuMat d_position;
133
134         alg->setTemplate(d_templ);
135
136         tm.start();
137
138         alg->detect(d_image, d_position);
139         d_position.download(position);
140
141         tm.stop();
142     }
143     else
144     {
145         alg->setTemplate(templ);
146
147         tm.start();
148
149         alg->detect(image, position);
150
151         tm.stop();
152     }
153
154     cout << "Found : " << position.size() << " objects" << endl;
155     cout << "Detection time : " << tm.getTimeMilli() << " ms" << endl;
156
157     Mat out;
158     cv::cvtColor(image, out, COLOR_GRAY2BGR);
159
160     for (size_t i = 0; i < position.size(); ++i)
161     {
162         Point2f pos(position[i][0], position[i][1]);
163         float scale = position[i][2];
164         float angle = position[i][3];
165
166         RotatedRect rect;
167         rect.center = pos;
168         rect.size = Size2f(templ.cols * scale, templ.rows * scale);
169         rect.angle = angle;
170
171         Point2f pts[4];
172         rect.points(pts);
173
174         line(out, pts[0], pts[1], Scalar(0, 0, 255), 3);
175         line(out, pts[1], pts[2], Scalar(0, 0, 255), 3);
176         line(out, pts[2], pts[3], Scalar(0, 0, 255), 3);
177         line(out, pts[3], pts[0], Scalar(0, 0, 255), 3);
178     }
179
180     imshow("out", out);
181     waitKey();
182
183     return 0;
184 }