OpenCV——霍夫变换圆检测

一、主要函数

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 );

   HoughCircles该函数使用霍夫变换在灰度图像中查找圆。

  • image:输入图像,需要为 8 位的灰度单通道图像。
  • circle:找到的圆的输出向量。每个向量被编码为3或4个元素的浮点型向量 ( x , y , r a d i u s ) (x, y, radius) (x,y,radius) ( x , y , r a d i u s , v o t e s ) (x, y, radius, votes) (x,y,radius,votes)
  • method:检测方法,参见HoughModes。可用的方法是HOUGH_GRADIENTHOUGH_GRADIENT_ALT
  • dp:累加器分辨率与图像分辨率的反比。当Dp =1时,累加器与输入图像具有相同的分辨率。如果dp=2,累加器的宽度和高度减半。HOUGH_GRADIENT_ALT方法的推荐值是dp=1.5,除非需要检测一些非常小的圆。
  • minDist:两个圆心之间的最小距离。若两圆心距离 < minDist,则认为是同一个圆。如果参数太小,可能会在检测到一个真实的圆的同时,检测到多个邻居圆。如果太大,可能会漏掉一些圆圈。
  • param1:第一个method-specific参数。对于HOUGH_GRADIENTHOUGH_GRADIENT_ALT,它是传递给Canny边缘检测器的两个阈值中较高的阈值(较低的阈值小两倍)。注意,HOUGH_GRADIENT_ALT使用Scharr算法来计算图像的导数,所以阈值通常应较高,如300或正常曝光和对比图像。
  • param2:第二个method-specific参数。对于HOUGH_GRADIENT,它是圆的累加器阈值在检测阶段居中。它越小,越多可能会检测到假圈。对应于较大累加器值的圆将为返回第一个。在HOUGH_GRADIENT_ALT算法的情况下,这是圆的“完美”度量。它越接近1,算法选择的圆形状越好。在大多数情况下,0.9应该就可以了。如果你想更好地检测小圆,你可以把它降低到0.85,0.8甚至更少。但也要尽量限制搜索范围在[minRadius, maxRadius],以避免出现许多错误的圆圈。
  • minRadius:圆半径的最小值。
  • maxRadius:圆半径的最大值。如果<= 0,则使用最大图像尺寸。如果< 0,则返回的结果中:HOUGH_GRADIENT求圆心而不求半径。HOUGH_GRADIENT_ALT计算圆的半径和圆心。

二、C++代码

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main(int argc, char** argv) 
{
    
    
	// ----------------------读取数据---------------------------
	cv::Mat src = cv::imread("圆.jpg");
	if (src.empty()) 
	{
    
    
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	cv::namedWindow("Circle", cv::WINDOW_AUTOSIZE);
	imshow("Circle", src);
	// ---------------------转灰度图----------------------------
	cv::Mat grayImg;
	cv::cvtColor(src, grayImg, cv::COLOR_BGR2GRAY);
	vector<cv::Vec3f>circles;
	int hough_value = 60;
	// --------------------霍夫圆检测---------------------------
	cv::HoughCircles(grayImg, circles, cv::HOUGH_GRADIENT, 1, 15, 100, hough_value, 15, 100);
	cv::Mat houghcircle = src.clone();
	for (int i = 0; i < circles.size(); ++i) 
	{
    
    
		circle(houghcircle, cv::Point(circles[i][0], circles[i][1]), circles[i][2], cv::Scalar(0, 0, 255), 2);
	}
	imwrite("houghcircle.jpg", houghcircle);
	imshow("houghcircle", houghcircle);
	cv::waitKey(0);
	return 0;
}

三、python代码

import cv2


# -------------------------读取数据----------------------------
img = cv2.imread('circle.jpg')
# ------------------------转为灰度图---------------------------
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# ------------------------霍夫圆检测-----------------------
circles = cv2.HoughCircles(gray_img, cv2.HOUGH_GRADIENT, 1, 15, param1=100, param2=80, minRadius=15, maxRadius=100)

for i in circles[0]:
    img = cv2.circle(img, (i[0], i[1]), int(i[2]), (0, 0, 255), 3)
cv2.imshow('circle', img)
cv2.waitKey(0)

四、结果展示

1、原始图像

在这里插入图片描述

2、检测结果

在这里插入图片描述

五、参考链接

[1] Opencv霍夫变换圆检测实战之检测硬币(C++)
[2] 霍夫变换检测圆形 -opencv

猜你喜欢

转载自blog.csdn.net/qq_36686437/article/details/127313258