├── Geometric_matching.cpp ├── LICENSE ├── README.md ├── image.png └── template_small_2.png /Geometric_matching.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "opencv2/opencv.hpp" 3 | #include "opencv2/cudaimgproc.hpp" 4 | 5 | using namespace std; 6 | using namespace cv; 7 | 8 | const bool use_gpu = true; 9 | 10 | int main() 11 | { 12 | Mat img_template = imread("template_small_2.png", IMREAD_GRAYSCALE); 13 | Mat img = imread("image.png", IMREAD_GRAYSCALE); 14 | 15 | Ptr guil = use_gpu ? cuda::createGeneralizedHoughGuil() : createGeneralizedHoughGuil(); 16 | 17 | guil->setMinDist(100); 18 | guil->setLevels(360); 19 | guil->setDp(4); 20 | guil->setMaxBufferSize(4000); 21 | 22 | guil->setMinAngle(0); 23 | guil->setMaxAngle(360); 24 | guil->setAngleStep(1); 25 | guil->setAngleThresh(15000); 26 | 27 | guil->setMinScale(0.9); 28 | guil->setMaxScale(1.1); 29 | guil->setScaleStep(0.05); 30 | guil->setScaleThresh(1000); 31 | 32 | guil->setPosThresh(400); 33 | //guil->setCannyHighThresh(230); 34 | //guil->setCannyLowThresh(150); 35 | 36 | double sobelScale = 0.05; 37 | int sobelKernelSize = 5; 38 | int cannyHigh = 230; 39 | int cannyLow = 150; 40 | 41 | Mat canny; 42 | Canny(img, canny, cannyHigh, cannyLow); 43 | namedWindow("canny", WINDOW_NORMAL); 44 | imshow("canny", canny); 45 | 46 | Mat dx; 47 | Sobel(img, dx, CV_32F, 1, 0, sobelKernelSize, sobelScale); 48 | namedWindow("dx", WINDOW_NORMAL); 49 | imshow("dx", dx); 50 | 51 | Mat dy; 52 | Sobel(img, dy, CV_32F, 0, 1, sobelKernelSize, sobelScale); 53 | namedWindow("dy", WINDOW_NORMAL); 54 | imshow("dy", dy); 55 | 56 | Mat canny_template; 57 | Canny(img_template, canny_template, cannyHigh, cannyLow); 58 | namedWindow("canny_template", WINDOW_NORMAL); 59 | imshow("canny_template", canny_template); 60 | 61 | Mat dx_template; 62 | Sobel(img_template, dx_template, CV_32F, 1, 0, sobelKernelSize, sobelScale); 63 | namedWindow("dx_template", WINDOW_NORMAL); 64 | imshow("dx_template", dx_template); 65 | 66 | Mat dy_template; 67 | Sobel(img_template, dy_template, CV_32F, 0, 1, sobelKernelSize, sobelScale); 68 | namedWindow("dy_template", WINDOW_NORMAL); 69 | imshow("dy_template", dy_template); 70 | 71 | vector position; 72 | TickMeter tm; 73 | Mat votes; 74 | 75 | if (use_gpu) { 76 | cuda::GpuMat d_template(img_template); 77 | cuda::GpuMat d_edges_template(canny_template); 78 | cuda::GpuMat d_image(img); 79 | cuda::GpuMat d_x(dx); 80 | cuda::GpuMat d_dx_template(dx_template); 81 | cuda::GpuMat d_y(dy); 82 | cuda::GpuMat d_dy_template(dy_template); 83 | cuda::GpuMat d_canny(canny); 84 | cuda::GpuMat d_position; 85 | cuda::GpuMat d_votes; 86 | 87 | guil->setTemplate(d_edges_template, d_dx_template, d_dy_template); 88 | 89 | tm.start(); 90 | 91 | guil->detect(d_canny, d_x, d_y, d_position, d_votes); 92 | 93 | if (d_position.size().height != 0) { 94 | d_position.download(position); 95 | d_votes.download(votes); 96 | } 97 | 98 | tm.stop(); 99 | } 100 | else { 101 | guil->setTemplate(canny_template, dx_template, dy_template); 102 | 103 | tm.start(); 104 | 105 | guil->detect(canny, dx, dy, position, votes); 106 | 107 | tm.stop(); 108 | } 109 | 110 | cout << "Found : " << position.size() << " objects" << endl; 111 | cout << "Detection time : " << tm.getTimeMilli() << " ms" << endl; 112 | 113 | Mat out; 114 | cvtColor(img, out, COLOR_GRAY2BGR); 115 | int index = 0; 116 | Mat votes_int = Mat(votes.rows, votes.cols, CV_32SC3, votes.data, votes.step); 117 | for (auto& i : position) { 118 | Point2f pos(i[0], i[1]); 119 | float scale = i[2]; 120 | float angle = i[3]; 121 | 122 | RotatedRect rect; 123 | rect.center = pos; 124 | rect.size = Size2f(img_template.cols * scale, img_template.rows * scale); 125 | rect.angle = angle; 126 | 127 | Point2f pts[4]; 128 | rect.points(pts); 129 | 130 | line(out, pts[0], pts[1], Scalar(0, 255, 0), 3); 131 | line(out, pts[1], pts[2], Scalar(0, 255, 0), 3); 132 | line(out, pts[2], pts[3], Scalar(0, 255, 0), 3); 133 | line(out, pts[3], pts[0], Scalar(0, 255, 0), 3); 134 | 135 | int score = votes_int.at(index).val[0]; 136 | index++; 137 | string score_string = to_string(score); 138 | putText(out, score_string, rect.center, FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 255), 2); 139 | } 140 | 141 | namedWindow("out", WINDOW_NORMAL); 142 | imshow("out", out); 143 | waitKey(); 144 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 vivienmetayer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Generalized_Hough_OpenCV_sample 2 | Samlpe program using Generalized Hough transform with OpenCV to perform shape based matching 3 | -------------------------------------------------------------------------------- /image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivienmetayer/Generalized_Hough_OpenCV_sample/cc49e905f61cb355ebb655930bcc80c7fed53288/image.png -------------------------------------------------------------------------------- /template_small_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivienmetayer/Generalized_Hough_OpenCV_sample/cc49e905f61cb355ebb655930bcc80c7fed53288/template_small_2.png --------------------------------------------------------------------------------