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