Commit be5c9103 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

Merge pull request #3443 from HelenWong:bug3363Fix

parents f61db41d e88bf2bc
...@@ -280,7 +280,7 @@ The function can be used to initialize a point-based tracker of an object. ...@@ -280,7 +280,7 @@ The function can be used to initialize a point-based tracker of an object.
HoughCircles HoughCircles
------------ ------------
Finds circles in a grayscale image using the Hough transform. Finds circles in a grayscale image using a modification of the Hough transform.
.. ocv:function:: void HoughCircles( InputArray image, OutputArray circles, int method, double dp, double minDist, double param1=100, double param2=100, int minRadius=0, int maxRadius=0 ) .. ocv:function:: void HoughCircles( InputArray image, OutputArray circles, int method, double dp, double minDist, double param1=100, double param2=100, int minRadius=0, int maxRadius=0 )
...@@ -308,8 +308,6 @@ Finds circles in a grayscale image using the Hough transform. ...@@ -308,8 +308,6 @@ Finds circles in a grayscale image using the Hough transform.
:param maxRadius: Maximum circle radius. :param maxRadius: Maximum circle radius.
The function finds circles in a grayscale image using a modification of the Hough transform.
Example: :: Example: ::
#include <opencv2/imgproc.hpp> #include <opencv2/imgproc.hpp>
...@@ -343,6 +341,8 @@ Example: :: ...@@ -343,6 +341,8 @@ Example: ::
return 0; return 0;
} }
.. note:: The elements of the output vector of found circles ("circles" in the above example) are sorted in descending order of accumulator values. This way, the centres with the most supporting pixels appear first.
.. note:: Usually the function detects the centers of circles well. However, it may fail to find correct radii. You can assist to the function by specifying the radius range ( ``minRadius`` and ``maxRadius`` ) if you know it. Or, you may ignore the returned radius, use only the center, and find the correct radius using an additional procedure. .. note:: Usually the function detects the centers of circles well. However, it may fail to find correct radii. You can assist to the function by specifying the radius range ( ``minRadius`` and ``maxRadius`` ) if you know it. Or, you may ignore the returned radius, use only the center, and find the correct radius using an additional procedure.
.. seealso:: .. seealso::
......
/*M/////////////////////////////////////////////////////////////////////////////////////// /*M///////////////////////////////////////////////////////////////////////////////////////
// //
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
// //
...@@ -1024,10 +1024,14 @@ icvHoughCirclesGradient( CvMat* img, float dp, float min_dist, ...@@ -1024,10 +1024,14 @@ icvHoughCirclesGradient( CvMat* img, float dp, float min_dist,
CvSeqReader reader; CvSeqReader reader;
edges.reset(cvCreateMat( img->rows, img->cols, CV_8UC1 )); edges.reset(cvCreateMat( img->rows, img->cols, CV_8UC1 ));
// Use the Canny Edge Detector to detect all the edges in the image.
cvCanny( img, edges, MAX(canny_threshold/2,1), canny_threshold, 3 ); cvCanny( img, edges, MAX(canny_threshold/2,1), canny_threshold, 3 );
dx.reset(cvCreateMat( img->rows, img->cols, CV_16SC1 )); dx.reset(cvCreateMat( img->rows, img->cols, CV_16SC1 ));
dy.reset(cvCreateMat( img->rows, img->cols, CV_16SC1 )); dy.reset(cvCreateMat( img->rows, img->cols, CV_16SC1 ));
/*Use the Sobel Derivative to compute the local gradient of all the non-zero pixels in the edge image.*/
cvSobel( img, dx, 1, 0, 3 ); cvSobel( img, dx, 1, 0, 3 );
cvSobel( img, dy, 0, 1, 3 ); cvSobel( img, dy, 0, 1, 3 );
...@@ -1038,6 +1042,8 @@ icvHoughCirclesGradient( CvMat* img, float dp, float min_dist, ...@@ -1038,6 +1042,8 @@ icvHoughCirclesGradient( CvMat* img, float dp, float min_dist,
cvZero(accum); cvZero(accum);
storage.reset(cvCreateMemStorage()); storage.reset(cvCreateMemStorage());
/* Create sequences for the nonzero pixels in the edge image and the centers of circles
which could be detected.*/
nz = cvCreateSeq( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage ); nz = cvCreateSeq( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage );
centers = cvCreateSeq( CV_32SC1, sizeof(CvSeq), sizeof(int), storage ); centers = cvCreateSeq( CV_32SC1, sizeof(CvSeq), sizeof(int), storage );
...@@ -1118,7 +1124,8 @@ icvHoughCirclesGradient( CvMat* img, float dp, float min_dist, ...@@ -1118,7 +1124,8 @@ icvHoughCirclesGradient( CvMat* img, float dp, float min_dist,
sort_buf.resize( MAX(center_count,nz_count) ); sort_buf.resize( MAX(center_count,nz_count) );
cvCvtSeqToArray( centers, &sort_buf[0] ); cvCvtSeqToArray( centers, &sort_buf[0] );
/*Sort candidate centers in descending order of their accumulator values, so that the centers
with the most supporting pixels appear first.*/
std::sort(sort_buf.begin(), sort_buf.begin() + center_count, cv::hough_cmp_gt(adata)); std::sort(sort_buf.begin(), sort_buf.begin() + center_count, cv::hough_cmp_gt(adata));
cvClearSeq( centers ); cvClearSeq( centers );
cvSeqPushMulti( centers, &sort_buf[0], center_count ); cvSeqPushMulti( centers, &sort_buf[0], center_count );
...@@ -1173,6 +1180,7 @@ icvHoughCirclesGradient( CvMat* img, float dp, float min_dist, ...@@ -1173,6 +1180,7 @@ icvHoughCirclesGradient( CvMat* img, float dp, float min_dist,
continue; continue;
dist_buf->cols = nz_count1; dist_buf->cols = nz_count1;
cvPow( dist_buf, dist_buf, 0.5 ); cvPow( dist_buf, dist_buf, 0.5 );
// Sort non-zero pixels according to their distance from the center.
std::sort(sort_buf.begin(), sort_buf.begin() + nz_count1, cv::hough_cmp_gt((int*)ddata)); std::sort(sort_buf.begin(), sort_buf.begin() + nz_count1, cv::hough_cmp_gt((int*)ddata));
dist_sum = start_dist = ddata[sort_buf[nz_count1-1]]; dist_sum = start_dist = ddata[sort_buf[nz_count1-1]];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment