generalized_hough.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #include <vector>
  2. #include <iostream>
  3. #include <string>
  4. #include "opencv2/core.hpp"
  5. #include "opencv2/core/utility.hpp"
  6. #include "opencv2/imgproc.hpp"
  7. #include "opencv2/cudaimgproc.hpp"
  8. #include "opencv2/highgui.hpp"
  9. using namespace std;
  10. using namespace cv;
  11. static Mat loadImage(const string& name)
  12. {
  13. Mat image = imread(name, IMREAD_GRAYSCALE);
  14. if (image.empty())
  15. {
  16. cerr << "Can't load image - " << name << endl;
  17. exit(-1);
  18. }
  19. return image;
  20. }
  21. int main(int argc, const char* argv[])
  22. {
  23. CommandLineParser cmd(argc, argv,
  24. "{ image i | ../data/pic1.png | input image }"
  25. "{ template t | templ.png | template image }"
  26. "{ full | | estimate scale and rotation }"
  27. "{ gpu | | use gpu version }"
  28. "{ minDist | 100 | minimum distance between the centers of the detected objects }"
  29. "{ levels | 360 | R-Table levels }"
  30. "{ votesThreshold | 30 | the accumulator threshold for the template centers at the detection stage. The smaller it is, the more false positions may be detected }"
  31. "{ angleThresh | 10000 | angle votes threshold }"
  32. "{ scaleThresh | 1000 | scale votes threshold }"
  33. "{ posThresh | 100 | position votes threshold }"
  34. "{ dp | 2 | inverse ratio of the accumulator resolution to the image resolution }"
  35. "{ minScale | 0.5 | minimal scale to detect }"
  36. "{ maxScale | 2 | maximal scale to detect }"
  37. "{ scaleStep | 0.05 | scale step }"
  38. "{ minAngle | 0 | minimal rotation angle to detect in degrees }"
  39. "{ maxAngle | 360 | maximal rotation angle to detect in degrees }"
  40. "{ angleStep | 1 | angle step in degrees }"
  41. "{ maxBufSize | 1000 | maximal size of inner buffers }"
  42. "{ help h ? | | print help message }"
  43. );
  44. cmd.about("This program demonstrates arbitrary object finding with the Generalized Hough transform.");
  45. if (cmd.has("help"))
  46. {
  47. cmd.printMessage();
  48. return 0;
  49. }
  50. const string templName = cmd.get<string>("template");
  51. const string imageName = cmd.get<string>("image");
  52. const bool full = cmd.has("full");
  53. const bool useGpu = cmd.has("gpu");
  54. const double minDist = cmd.get<double>("minDist");
  55. const int levels = cmd.get<int>("levels");
  56. const int votesThreshold = cmd.get<int>("votesThreshold");
  57. const int angleThresh = cmd.get<int>("angleThresh");
  58. const int scaleThresh = cmd.get<int>("scaleThresh");
  59. const int posThresh = cmd.get<int>("posThresh");
  60. const double dp = cmd.get<double>("dp");
  61. const double minScale = cmd.get<double>("minScale");
  62. const double maxScale = cmd.get<double>("maxScale");
  63. const double scaleStep = cmd.get<double>("scaleStep");
  64. const double minAngle = cmd.get<double>("minAngle");
  65. const double maxAngle = cmd.get<double>("maxAngle");
  66. const double angleStep = cmd.get<double>("angleStep");
  67. const int maxBufSize = cmd.get<int>("maxBufSize");
  68. if (!cmd.check())
  69. {
  70. cmd.printErrors();
  71. return -1;
  72. }
  73. Mat templ = loadImage(templName);
  74. Mat image = loadImage(imageName);
  75. Ptr<GeneralizedHough> alg;
  76. if (!full)
  77. {
  78. Ptr<GeneralizedHoughBallard> ballard = useGpu ? cuda::createGeneralizedHoughBallard() : createGeneralizedHoughBallard();
  79. ballard->setMinDist(minDist);
  80. ballard->setLevels(levels);
  81. ballard->setDp(dp);
  82. ballard->setMaxBufferSize(maxBufSize);
  83. ballard->setVotesThreshold(votesThreshold);
  84. alg = ballard;
  85. }
  86. else
  87. {
  88. Ptr<GeneralizedHoughGuil> guil = useGpu ? cuda::createGeneralizedHoughGuil() : createGeneralizedHoughGuil();
  89. guil->setMinDist(minDist);
  90. guil->setLevels(levels);
  91. guil->setDp(dp);
  92. guil->setMaxBufferSize(maxBufSize);
  93. guil->setMinAngle(minAngle);
  94. guil->setMaxAngle(maxAngle);
  95. guil->setAngleStep(angleStep);
  96. guil->setAngleThresh(angleThresh);
  97. guil->setMinScale(minScale);
  98. guil->setMaxScale(maxScale);
  99. guil->setScaleStep(scaleStep);
  100. guil->setScaleThresh(scaleThresh);
  101. guil->setPosThresh(posThresh);
  102. alg = guil;
  103. }
  104. vector<Vec4f> position;
  105. TickMeter tm;
  106. if (useGpu)
  107. {
  108. cuda::GpuMat d_templ(templ);
  109. cuda::GpuMat d_image(image);
  110. cuda::GpuMat d_position;
  111. alg->setTemplate(d_templ);
  112. tm.start();
  113. alg->detect(d_image, d_position);
  114. d_position.download(position);
  115. tm.stop();
  116. }
  117. else
  118. {
  119. alg->setTemplate(templ);
  120. tm.start();
  121. alg->detect(image, position);
  122. tm.stop();
  123. }
  124. cout << "Found : " << position.size() << " objects" << endl;
  125. cout << "Detection time : " << tm.getTimeMilli() << " ms" << endl;
  126. Mat out;
  127. cv::cvtColor(image, out, COLOR_GRAY2BGR);
  128. for (size_t i = 0; i < position.size(); ++i)
  129. {
  130. Point2f pos(position[i][0], position[i][1]);
  131. float scale = position[i][2];
  132. float angle = position[i][3];
  133. RotatedRect rect;
  134. rect.center = pos;
  135. rect.size = Size2f(templ.cols * scale, templ.rows * scale);
  136. rect.angle = angle;
  137. Point2f pts[4];
  138. rect.points(pts);
  139. line(out, pts[0], pts[1], Scalar(0, 0, 255), 3);
  140. line(out, pts[1], pts[2], Scalar(0, 0, 255), 3);
  141. line(out, pts[2], pts[3], Scalar(0, 0, 255), 3);
  142. line(out, pts[3], pts[0], Scalar(0, 0, 255), 3);
  143. }
  144. imshow("out", out);
  145. waitKey();
  146. return 0;
  147. }