OpenCV——霍夫变换圆检测
目录
- 一、主要函数
- 二、C++代码
- 三、python代码
- 四、结果展示
- 1、原始图像
- 2、检测结果
- 五、参考链接
一、主要函数
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_GRADIENT
和HOUGH_GRADIENT_ALT
。dp
:累加器分辨率与图像分辨率的反比。当Dp =1时,累加器与输入图像具有相同的分辨率。如果dp=2,累加器的宽度和高度减半。HOUGH_GRADIENT_ALT
方法的推荐值是dp=1.5,除非需要检测一些非常小的圆。minDist
:两个圆心之间的最小距离。若两圆心距离 < minDist,则认为是同一个圆。如果参数太小,可能会在检测到一个真实的圆的同时,检测到多个邻居圆。如果太大,可能会漏掉一些圆圈。param1
:第一个method-specific参数。对于HOUGH_GRADIENT
和HOUGH_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