morphology.cpp 4.1 KB

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