1 #include <iostream>
2
3 #include "opencv2/imgproc.hpp"
4 #include "opencv2/highgui.hpp"
5 #include "opencv2/cudafilters.hpp"
6 #include "opencv2/cudaimgproc.hpp"
7
8 using namespace std;
9 using namespace cv;
10
11 class App
12 {
13 public:
14 App(int argc, const char* argv[]);
15
16 int run();
17
18 private:
19 void help();
20
21 void OpenClose();
22 void ErodeDilate();
23
24 static void OpenCloseCallback(int, void*);
25 static void ErodeDilateCallback(int, void*);
26
27 cuda::GpuMat src, dst;
28
29 int element_shape;
30
31 int max_iters;
32 int open_close_pos;
33 int erode_dilate_pos;
34 };
35
App(int argc,const char * argv[])36 App::App(int argc, const char* argv[])
37 {
38 element_shape = MORPH_RECT;
39 open_close_pos = erode_dilate_pos = max_iters = 10;
40
41 if (argc == 2 && String(argv[1]) == "--help")
42 {
43 help();
44 exit(0);
45 }
46
47 String filename = argc == 2 ? argv[1] : "../data/baboon.jpg";
48
49 Mat img = imread(filename);
50 if (img.empty())
51 {
52 cerr << "Can't open image " << filename.c_str() << endl;
53 exit(-1);
54 }
55
56 src.upload(img);
57 if (src.channels() == 3)
58 {
59 // gpu support only 4th channel images
60 cuda::GpuMat src4ch;
61 cuda::cvtColor(src, src4ch, COLOR_BGR2BGRA);
62 src = src4ch;
63 }
64
65 help();
66
67 cuda::printShortCudaDeviceInfo(cuda::getDevice());
68 }
69
run()70 int App::run()
71 {
72 // create windows for output images
73 namedWindow("Open/Close");
74 namedWindow("Erode/Dilate");
75
76 createTrackbar("iterations", "Open/Close", &open_close_pos, max_iters * 2 + 1, OpenCloseCallback, this);
77 createTrackbar("iterations", "Erode/Dilate", &erode_dilate_pos, max_iters * 2 + 1, ErodeDilateCallback, this);
78
79 for(;;)
80 {
81 OpenClose();
82 ErodeDilate();
83
84 char c = (char) waitKey();
85
86 switch (c)
87 {
88 case 27:
89 return 0;
90 break;
91
92 case 'e':
93 element_shape = MORPH_ELLIPSE;
94 break;
95
96 case 'r':
97 element_shape = MORPH_RECT;
98 break;
99
100 case 'c':
101 element_shape = MORPH_CROSS;
102 break;
103
104 case ' ':
105 element_shape = (element_shape + 1) % 3;
106 break;
107 }
108 }
109 }
110
help()111 void App::help()
112 {
113 cout << "Show off image morphology: erosion, dialation, open and close \n";
114 cout << "Call: \n";
115 cout << " gpu-example-morphology [image] \n";
116 cout << "This program also shows use of rect, ellipse and cross kernels \n" << endl;
117
118 cout << "Hot keys: \n";
119 cout << "\tESC - quit the program \n";
120 cout << "\tr - use rectangle structuring element \n";
121 cout << "\te - use elliptic structuring element \n";
122 cout << "\tc - use cross-shaped structuring element \n";
123 cout << "\tSPACE - loop through all the options \n" << endl;
124 }
125
OpenClose()126 void App::OpenClose()
127 {
128 int n = open_close_pos - max_iters;
129 int an = n > 0 ? n : -n;
130
131 Mat element = getStructuringElement(element_shape, Size(an*2+1, an*2+1), Point(an, an));
132
133 if (n < 0)
134 {
135 Ptr<cuda::Filter> openFilter = cuda::createMorphologyFilter(MORPH_OPEN, src.type(), element);
136 openFilter->apply(src, dst);
137 }
138 else
139 {
140 Ptr<cuda::Filter> closeFilter = cuda::createMorphologyFilter(MORPH_CLOSE, src.type(), element);
141 closeFilter->apply(src, dst);
142 }
143
144 Mat h_dst(dst);
145 imshow("Open/Close", h_dst);
146 }
147
ErodeDilate()148 void App::ErodeDilate()
149 {
150 int n = erode_dilate_pos - max_iters;
151 int an = n > 0 ? n : -n;
152
153 Mat element = getStructuringElement(element_shape, Size(an*2+1, an*2+1), Point(an, an));
154
155 if (n < 0)
156 {
157 Ptr<cuda::Filter> erodeFilter = cuda::createMorphologyFilter(MORPH_ERODE, src.type(), element);
158 erodeFilter->apply(src, dst);
159 }
160 else
161 {
162 Ptr<cuda::Filter> dilateFilter = cuda::createMorphologyFilter(MORPH_DILATE, src.type(), element);
163 dilateFilter->apply(src, dst);
164 }
165
166 Mat h_dst(dst);
167 imshow("Erode/Dilate", h_dst);
168 }
169
OpenCloseCallback(int,void * data)170 void App::OpenCloseCallback(int, void* data)
171 {
172 App* thiz = (App*) data;
173 thiz->OpenClose();
174 }
175
ErodeDilateCallback(int,void * data)176 void App::ErodeDilateCallback(int, void* data)
177 {
178 App* thiz = (App*) data;
179 thiz->ErodeDilate();
180 }
181
main(int argc,const char * argv[])182 int main(int argc, const char* argv[])
183 {
184 App app(argc, argv);
185 return app.run();
186 }
187