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 8using namespace std; 9using namespace cv; 10 11class App 12{ 13public: 14 App(int argc, const char* argv[]); 15 16 int run(); 17 18private: 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 36App::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 70int 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 111void 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 126void 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 148void 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 170void App::OpenCloseCallback(int, void* data) 171{ 172 App* thiz = (App*) data; 173 thiz->OpenClose(); 174} 175 176void App::ErodeDilateCallback(int, void* data) 177{ 178 App* thiz = (App*) data; 179 thiz->ErodeDilate(); 180} 181 182int main(int argc, const char* argv[]) 183{ 184 App app(argc, argv); 185 return app.run(); 186} 187