1 /**
2 * @file HoughCircle_Demo.cpp
3 * @brief Demo code for Hough Transform
4 * @author OpenCV team
5 */
6
7 #include "opencv2/imgcodecs.hpp"
8 #include "opencv2/highgui/highgui.hpp"
9 #include "opencv2/imgproc/imgproc.hpp"
10 #include <iostream>
11
12 using namespace std;
13 using namespace cv;
14
15 namespace
16 {
17 // windows and trackbars name
18 const std::string windowName = "Hough Circle Detection Demo";
19 const std::string cannyThresholdTrackbarName = "Canny threshold";
20 const std::string accumulatorThresholdTrackbarName = "Accumulator Threshold";
21 const std::string usage = "Usage : tutorial_HoughCircle_Demo <path_to_input_image>\n";
22
23 // initial and max values of the parameters of interests.
24 const int cannyThresholdInitialValue = 200;
25 const int accumulatorThresholdInitialValue = 50;
26 const int maxAccumulatorThreshold = 200;
27 const int maxCannyThreshold = 255;
28
HoughDetection(const Mat & src_gray,const Mat & src_display,int cannyThreshold,int accumulatorThreshold)29 void HoughDetection(const Mat& src_gray, const Mat& src_display, int cannyThreshold, int accumulatorThreshold)
30 {
31 // will hold the results of the detection
32 std::vector<Vec3f> circles;
33 // runs the actual detection
34 HoughCircles( src_gray, circles, HOUGH_GRADIENT, 1, src_gray.rows/8, cannyThreshold, accumulatorThreshold, 0, 0 );
35
36 // clone the colour, input image for displaying purposes
37 Mat display = src_display.clone();
38 for( size_t i = 0; i < circles.size(); i++ )
39 {
40 Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
41 int radius = cvRound(circles[i][2]);
42 // circle center
43 circle( display, center, 3, Scalar(0,255,0), -1, 8, 0 );
44 // circle outline
45 circle( display, center, radius, Scalar(0,0,255), 3, 8, 0 );
46 }
47
48 // shows the results
49 imshow( windowName, display);
50 }
51 }
52
53
main(int argc,char ** argv)54 int main(int argc, char** argv)
55 {
56 Mat src, src_gray;
57
58 if (argc < 2)
59 {
60 std::cerr<<"No input image specified\n";
61 std::cout<<usage;
62 return -1;
63 }
64
65 // Read the image
66 src = imread( argv[1], 1 );
67
68 if( src.empty() )
69 {
70 std::cerr<<"Invalid input image\n";
71 std::cout<<usage;
72 return -1;
73 }
74
75 // Convert it to gray
76 cvtColor( src, src_gray, COLOR_BGR2GRAY );
77
78 // Reduce the noise so we avoid false circle detection
79 GaussianBlur( src_gray, src_gray, Size(9, 9), 2, 2 );
80
81 //declare and initialize both parameters that are subjects to change
82 int cannyThreshold = cannyThresholdInitialValue;
83 int accumulatorThreshold = accumulatorThresholdInitialValue;
84
85 // create the main window, and attach the trackbars
86 namedWindow( windowName, WINDOW_AUTOSIZE );
87 createTrackbar(cannyThresholdTrackbarName, windowName, &cannyThreshold,maxCannyThreshold);
88 createTrackbar(accumulatorThresholdTrackbarName, windowName, &accumulatorThreshold, maxAccumulatorThreshold);
89
90 // infinite loop to display
91 // and refresh the content of the output image
92 // until the user presses q or Q
93 int key = 0;
94 while(key != 'q' && key != 'Q')
95 {
96 // those paramaters cannot be =0
97 // so we must check here
98 cannyThreshold = std::max(cannyThreshold, 1);
99 accumulatorThreshold = std::max(accumulatorThreshold, 1);
100
101 //runs the detection, and update the display
102 HoughDetection(src_gray, src, cannyThreshold, accumulatorThreshold);
103
104 // get user key
105 key = waitKey(10);
106 }
107
108 return 0;
109 }
110