原理介绍:
opencv —— HoughCircles 霍夫圆变换原理及圆检测
霍夫变换(Hough Transform)
霍夫变换 - 圆检测 (Hough Circle transform)
霍夫圆算法是一种用于检测图像中圆形区域的算法。OpenCV 霍夫圆变换对标准霍夫圆变换做了运算上的优化。它采用的是 “霍夫梯度法”。
HoughCircles 函数可以利用霍夫变换算法检测出灰度图中的圆。
函数原型:
CV_EXPORTS_W void HoughCircles( InputArray image, OutputArray circles,
int method, double dp, double minDist,
double param1 = 100, double param2 = 100,
int minRadius = 0, int maxRadius = 0 );
@brief Finds circles in a grayscale image using the Hough transform.使用霍夫变换在灰度图中检测圆
The function finds circles in a grayscale image using a modification of the Hough transform.
@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, in the case of #HOUGH_GRADIENT method you may set maxRadius to a negative number to return centers only without radius search, and find the correct radius using an additional procedure.
此函数可以很容易地检测出圆心,但是可能找不到合适地圆半径。我们可以通过 minRadius 和 maxRadius 两个参数指定最大和最小圆半径,来辅助圆检测的结果。或者可以直接忽略返回半径,让二者均为默认值,只用 HoughCircles 函数检测出圆心,用额外步骤进一步确定半径。
It also helps to smooth image a bit unless it's already soft. For example,GaussianBlur() with 7x7 kernel and 1.5x1.5 sigma or similar blurring may help.
除非图像已经很柔和,否则还可以使图像稍微平滑一些 例如,具有7x7内核和1.5x1.5 sigma或类似模糊效果的GaussianBlur()可能会有所帮助
@param image 8-bit, single-channel, grayscale input image.
@param circles Output vector of found circles. Each vector is encoded as 3 or 4 element
floating-point vector .
@param method Detection method, see #HoughModes. The available methods are #HOUGH_GRADIENT and #HOUGH_GRADIENT_ALT.
@param dp Inverse ratio of the accumulator resolution to the image resolution. For example, if dp=1 , the accumulator has the same resolution as the input image. If dp=2 , the accumulator has half as big width and height. For #HOUGH_GRADIENT_ALT the recommended value is dp=1.5, unless some small very circles need to be detected.
累加器分辨率与图像分辨率的反比 例如,如果 dp = 1,累加器具有与输入图像相同的分辨率 如果dp = 2,则累加器具有 宽度和高度的一半 对于#HOUGH GRADIENT ALT,建议值为dp = 1.5, 除非需要检测到一些很小的圆圈
@param minDist Minimum distance between the centers of the detected circles. If the parameter is too small, multiple neighbor circles may be falsely detected in addition to a true one. If it is too large, some circles may be missed.
被检测圆的中心之间的最小距离。如果参数太小,可能会错误地检测到多个邻居圆,而不是一个真邻居圆。如果太大,可能会漏掉一些圆圈。
@param param1 First method-specific parameter. In case of #HOUGH_GRADIENT and #HOUGH_GRADIENT_ALT, it is the higher threshold of the two passed to the Canny edge detector (the lower one is twice smaller).
Note that #HOUGH_GRADIENT_ALT uses #Scharr algorithm to compute image derivatives, so the threshold value shough normally be higher, such as 300 or normally exposed and contrasty images.
第一个method-specific参数。在#HOUGH GRADIENT和#HOUGH ALT的情况下,它是传递给Canny边缘检测器的两个较高的阈值(较低的那个小1 / 2)。注意,#HOUGH梯度ALT使用#Scharr算法来计算图像导数,所以阈值通常会更高,例如300或正常曝光和对比度图像。
@param param2 Second method-specific parameter. In case of #HOUGH_GRADIENT, it is the accumulator threshold for the circle centers at the detection stage. The smaller it is, the more false circles may be detected. Circles, corresponding to the larger accumulator values, will be returned first. In the case of #HOUGH_GRADIENT_ALT algorithm, this is the circle "perfectness" measure. The closer it to 1, the better shaped circles algorithm selects. In most cases 0.9 should be fine.
If you want get better detection of small circles, you may decrease it to 0.85, 0.8 or even less. But then also try to limit the search range [minRadius, maxRadius] to avoid many false circles.
第二种方法特定的参数; 如果是#HOUGH GRADIENT,则为 圆的累加器阈值在检测阶段居中 越小越多 可能会检测到错误的圆圈 与较大的累加器值相对应的圆将是 首先返回 在#HOUGH GRADIENT ALT算法的情况下,这是圈 perfectness 度量 它越接近1,则选择的形状更好的圆形算法 在大多数情况下,0.9应该可以 如果要更好地检测小圆圈,可以将其降低到0.85 0.8甚至更低 但是,然后还要尝试限制搜索范围[minRadius,maxRadius],以避免出现许多错误的圆圈
@param minRadius Minimum circle radius.
@param maxRadius Maximum circle radius. If <= 0, uses the maximum image dimension. If < 0, #HOUGH_GRADIENT returns centers without finding the radius. #HOUGH_GRADIENT_ALT always computes circle radiuses.
- image,输入图像,即源图像,需要为 8 位的灰度单通道图像。
- circles,调用 HoughCircles 函数后此参数存储了检测到的圆的输出矢量,每个矢量由包含了 3 个元素的浮点矢量(x,y,radius)表示。
- method,使用的检测方法,目前 OpenCV 中就霍夫梯度法一种可以使用,标识符为 HOUGH_GRADIENT。
- dp,累加面分辨率(大小) = 原始图像分辨率(大小) × 1/dp。默认 dp = 1 时,两者分辨率相同。
- minDist,两个圆心之间的最小距离。若两圆心距离 < minDist,则认为是同一个圆。
- param1,Canny 边缘检测的高阈值,低阈值被自动置为高阈值的一半,默认为 100。
- param2,累加平面某点是否是圆心的判定阈值。它越大,能通过检测的圆就更接近完美的圆形,默认为 100。
- minRadius,圆半径的最小值。默认为 0。
- maxRadius,圆半径的最大值,默认为 0。
参数 | 描述 |
---|---|
InputArray image | 8位、单通道、灰度输入图像 |
HoughMethods method | 目前,唯一的实现方法是HoughCirclesMethod.Gradient |
double dp | 累加器分辨率与图像分辨率的反比。dp=1 |
double minDist | 检测到的圆的中心之间的最小距离。可以分辨时两个圆还是同心圆 |
double param1 = 100 | 第一个方法特定的参数。[默认值是100],边缘检测的低阈值 |
double param2 = 100 | 第二个方法特定于参数。 [默认值是100],中心点累加器阈值,候选圆心 |
int minRadius = 0 | 最小半径 |
int maxRadius = 0 | 最大半径 |
#include
#include
using namespace std;
using namespace cv;
int hough_value = 55;
Mat src, gray;
void hough_change(int, void*) {
vectorcircles; //minDist 和 param2 数值的设定是关键
HoughCircles(gray, circles, HOUGH_GRADIENT, 1, 10, 110, hough_value, 0, 0);
Mat show = src.clone();
for (int i = 0; i < circles.size(); i++) {
circle(show, Point(circles[i][0], circles[i][1]), circles[i][2], Scalar(0, 0, 255), 2);
}
imshow("show", show);
}
int main() {
src = imread("circles.bmp");
GaussianBlur(src, src, Size(3, 3), 0, 0);
imshow("原图", src);
cvtColor(src, gray, COLOR_BGR2GRAY);
namedWindow("show");
createTrackbar("hough_value", "show", &hough_value, 200, hough_change);
hough_change(0, 0);
waitKey(0);
}
使用HoughCircles()函数进行圆检测,其中参数的选择很关键,尤其是minDist 和 param2 两个参数的数值选择,决定着圆检测效果的好坏。