123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- #include <vector>
- #include <iostream>
- #include <string>
- #include "opencv2/core.hpp"
- #include "opencv2/core/utility.hpp"
- #include "opencv2/imgproc.hpp"
- #include "opencv2/cudaimgproc.hpp"
- #include "opencv2/highgui.hpp"
- using namespace std;
- using namespace cv;
- static Mat loadImage(const string& name)
- {
- Mat image = imread(name, IMREAD_GRAYSCALE);
- if (image.empty())
- {
- cerr << "Can't load image - " << name << endl;
- exit(-1);
- }
- return image;
- }
- int main(int argc, const char* argv[])
- {
- CommandLineParser cmd(argc, argv,
- "{ image i | ../data/pic1.png | input image }"
- "{ template t | templ.png | template image }"
- "{ full | | estimate scale and rotation }"
- "{ gpu | | use gpu version }"
- "{ minDist | 100 | minimum distance between the centers of the detected objects }"
- "{ levels | 360 | R-Table levels }"
- "{ votesThreshold | 30 | the accumulator threshold for the template centers at the detection stage. The smaller it is, the more false positions may be detected }"
- "{ angleThresh | 10000 | angle votes threshold }"
- "{ scaleThresh | 1000 | scale votes threshold }"
- "{ posThresh | 100 | position votes threshold }"
- "{ dp | 2 | inverse ratio of the accumulator resolution to the image resolution }"
- "{ minScale | 0.5 | minimal scale to detect }"
- "{ maxScale | 2 | maximal scale to detect }"
- "{ scaleStep | 0.05 | scale step }"
- "{ minAngle | 0 | minimal rotation angle to detect in degrees }"
- "{ maxAngle | 360 | maximal rotation angle to detect in degrees }"
- "{ angleStep | 1 | angle step in degrees }"
- "{ maxBufSize | 1000 | maximal size of inner buffers }"
- "{ help h ? | | print help message }"
- );
- cmd.about("This program demonstrates arbitrary object finding with the Generalized Hough transform.");
- if (cmd.has("help"))
- {
- cmd.printMessage();
- return 0;
- }
- const string templName = cmd.get<string>("template");
- const string imageName = cmd.get<string>("image");
- const bool full = cmd.has("full");
- const bool useGpu = cmd.has("gpu");
- const double minDist = cmd.get<double>("minDist");
- const int levels = cmd.get<int>("levels");
- const int votesThreshold = cmd.get<int>("votesThreshold");
- const int angleThresh = cmd.get<int>("angleThresh");
- const int scaleThresh = cmd.get<int>("scaleThresh");
- const int posThresh = cmd.get<int>("posThresh");
- const double dp = cmd.get<double>("dp");
- const double minScale = cmd.get<double>("minScale");
- const double maxScale = cmd.get<double>("maxScale");
- const double scaleStep = cmd.get<double>("scaleStep");
- const double minAngle = cmd.get<double>("minAngle");
- const double maxAngle = cmd.get<double>("maxAngle");
- const double angleStep = cmd.get<double>("angleStep");
- const int maxBufSize = cmd.get<int>("maxBufSize");
- if (!cmd.check())
- {
- cmd.printErrors();
- return -1;
- }
- Mat templ = loadImage(templName);
- Mat image = loadImage(imageName);
- Ptr<GeneralizedHough> alg;
- if (!full)
- {
- Ptr<GeneralizedHoughBallard> ballard = useGpu ? cuda::createGeneralizedHoughBallard() : createGeneralizedHoughBallard();
- ballard->setMinDist(minDist);
- ballard->setLevels(levels);
- ballard->setDp(dp);
- ballard->setMaxBufferSize(maxBufSize);
- ballard->setVotesThreshold(votesThreshold);
- alg = ballard;
- }
- else
- {
- Ptr<GeneralizedHoughGuil> guil = useGpu ? cuda::createGeneralizedHoughGuil() : createGeneralizedHoughGuil();
- guil->setMinDist(minDist);
- guil->setLevels(levels);
- guil->setDp(dp);
- guil->setMaxBufferSize(maxBufSize);
- guil->setMinAngle(minAngle);
- guil->setMaxAngle(maxAngle);
- guil->setAngleStep(angleStep);
- guil->setAngleThresh(angleThresh);
- guil->setMinScale(minScale);
- guil->setMaxScale(maxScale);
- guil->setScaleStep(scaleStep);
- guil->setScaleThresh(scaleThresh);
- guil->setPosThresh(posThresh);
- alg = guil;
- }
- vector<Vec4f> position;
- TickMeter tm;
- if (useGpu)
- {
- cuda::GpuMat d_templ(templ);
- cuda::GpuMat d_image(image);
- cuda::GpuMat d_position;
- alg->setTemplate(d_templ);
- tm.start();
- alg->detect(d_image, d_position);
- d_position.download(position);
- tm.stop();
- }
- else
- {
- alg->setTemplate(templ);
- tm.start();
- alg->detect(image, position);
- tm.stop();
- }
- cout << "Found : " << position.size() << " objects" << endl;
- cout << "Detection time : " << tm.getTimeMilli() << " ms" << endl;
- Mat out;
- cv::cvtColor(image, out, COLOR_GRAY2BGR);
- for (size_t i = 0; i < position.size(); ++i)
- {
- Point2f pos(position[i][0], position[i][1]);
- float scale = position[i][2];
- float angle = position[i][3];
- RotatedRect rect;
- rect.center = pos;
- rect.size = Size2f(templ.cols * scale, templ.rows * scale);
- rect.angle = angle;
- Point2f pts[4];
- rect.points(pts);
- line(out, pts[0], pts[1], Scalar(0, 0, 255), 3);
- line(out, pts[1], pts[2], Scalar(0, 0, 255), 3);
- line(out, pts[2], pts[3], Scalar(0, 0, 255), 3);
- line(out, pts[3], pts[0], Scalar(0, 0, 255), 3);
- }
- imshow("out", out);
- waitKey();
- return 0;
- }
|