morphology.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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 'd':
  79. element_shape = MORPH_DIAMOND;
  80. break;
  81. case ' ':
  82. element_shape = (element_shape + 1) % 4;
  83. break;
  84. }
  85. }
  86. }
  87. void App::help()
  88. {
  89. cout << "Show off image morphology: erosion, dialation, open and close \n";
  90. cout << "Call: \n";
  91. cout << " gpu-example-morphology [image] \n";
  92. cout << "This program also shows use of rect, ellipse, cross and diamond kernels \n" << endl;
  93. cout << "Hot keys: \n";
  94. cout << "\tESC - quit the program \n";
  95. cout << "\tr - use rectangle structuring element \n";
  96. cout << "\te - use elliptic structuring element \n";
  97. cout << "\tc - use cross-shaped structuring element \n";
  98. cout << "\td - use diamond-shaped structuring element \n";
  99. cout << "\tSPACE - loop through all the options \n" << endl;
  100. }
  101. void App::OpenClose()
  102. {
  103. int n = open_close_pos - max_iters;
  104. int an = n > 0 ? n : -n;
  105. Mat element = getStructuringElement(element_shape, Size(an*2+1, an*2+1), Point(an, an));
  106. if (n < 0)
  107. {
  108. Ptr<cuda::Filter> openFilter = cuda::createMorphologyFilter(MORPH_OPEN, src.type(), element);
  109. openFilter->apply(src, dst);
  110. }
  111. else
  112. {
  113. Ptr<cuda::Filter> closeFilter = cuda::createMorphologyFilter(MORPH_CLOSE, src.type(), element);
  114. closeFilter->apply(src, dst);
  115. }
  116. Mat h_dst(dst);
  117. imshow("Open/Close", h_dst);
  118. }
  119. void App::ErodeDilate()
  120. {
  121. int n = erode_dilate_pos - max_iters;
  122. int an = n > 0 ? n : -n;
  123. Mat element = getStructuringElement(element_shape, Size(an*2+1, an*2+1), Point(an, an));
  124. if (n < 0)
  125. {
  126. Ptr<cuda::Filter> erodeFilter = cuda::createMorphologyFilter(MORPH_ERODE, src.type(), element);
  127. erodeFilter->apply(src, dst);
  128. }
  129. else
  130. {
  131. Ptr<cuda::Filter> dilateFilter = cuda::createMorphologyFilter(MORPH_DILATE, src.type(), element);
  132. dilateFilter->apply(src, dst);
  133. }
  134. Mat h_dst(dst);
  135. imshow("Erode/Dilate", h_dst);
  136. }
  137. void App::OpenCloseCallback(int, void* data)
  138. {
  139. App* thiz = (App*) data;
  140. thiz->OpenClose();
  141. }
  142. void App::ErodeDilateCallback(int, void* data)
  143. {
  144. App* thiz = (App*) data;
  145. thiz->ErodeDilate();
  146. }
  147. int main(int argc, const char* argv[])
  148. {
  149. App app(argc, argv);
  150. return app.run();
  151. }