OpenCV学习笔记-霍夫变换圆检测
霍夫圆变换的基本原理和霍夫线变换类似,只是点对应的二维极径极角空间被三维的圆心点x, y还有半径r空间取代。
对直线来说,一条直线能由参数极径极角(r, θ)表示。而对圆来说,我们需要三个参数来表示一个圆,由于比直线检测多出一个维度,使得标准的霍夫圆检测需要大量的内存且速度比较慢。出于对运算效率的考虑,OpenCV实现的霍夫圆检测是一个比标准霍夫圆检测更为灵活的检测方法:霍夫梯度法,也叫2-1霍夫变换(21HT)。
霍夫梯度法:
它的原理依据是圆心一定是在圆上的每个点的模向量上,这些圆上点模向量的交点就是圆心,霍夫梯度法的第一步就是找到这些圆心,这样三维的累加平面就又转化为二维累加平面。第二步根据所有候选中心的边缘非0像素对其的支持程度来确定半径。
实现原理就是首先对图像进行模糊降噪,进行canny边缘检测,然后考虑边缘图像中的每一个非0点的局部梯度,通过Sebol()函数计算x, y方向上的sobel一阶导数得到梯度,利用得到的梯度,由斜率指定直线上的每一个点都在累加器中被累加,然后从累加器中这些点中选择候选的中心画圆。
执行步骤:
1、执行均值偏移滤波,消除噪声
2、转成灰度图
3、canny边缘检测
4、执行霍夫圆检测
5、绘制出检测到的圆
第一步和第二步可以根据实际情况调整顺序,但一定要消除噪声。
具体代码
import cv2 as cv import numpy as np from matplotlib import pyplot as plt def Hough_circle_demo(img): #均值偏移滤波 dst = cv.pyrMeanShiftFiltering(img, 10, 120) cv.imshow('filter', dst) #转成灰度图 gray = cv.cvtColor(dst, cv.COLOR_BGR2GRAY) cv.imshow('gray', gray) #canny边缘检测 edges = cv.Canny(gray, 50, 150, apertureSize=3) cv.imshow('canny', edges) #执行霍夫圆检测 circles = cv.HoughCircles(edges, cv.HOUGH_GRADIENT, 1, 20, param1=50, param2=30, minRadius=0, maxRadius=0) ''' HoughCircles(image, method, dp, minDist, circles=None, param1=None, param2=None, minRadius=None, maxRadius=None) image: 输入图像 method: 检测方法 minDist: 检测到圆心之间的最小距离 img.rows/8 circles: 返回结果 (x,y,r) param1: canny边缘函数的高阈值 param2: 圆心检测阈值 minRadius: 能检测到的最小圆半径 maxRadius: 能检测到的最大圆半径 ''' circles = np.uint16(np.around(circles)) #绘制出检测到的圆 for i in circles[0, :]: cv.circle(img, (i[0], i[1]), i[2], (0, 0, 255), 1) cv.circle(img, (i[0], i[1]), 2, (0, 255, 0), 2) cv.imshow('circles', img) img = cv.imread('img/target.jpg') cv.namedWindow('img',cv.WINDOW_AUTOSIZE) cv.imshow('img',img) Hough_circle_demo(img) cv.waitKey(0) cv.destroyAllWindows()
效果图对比:
cv.pyrMeanShiftFiltering(img, 10, 120),进行了canny边缘检测的结果
cv.pyrMeanShiftFiltering(img, 10, 100),执行了canny边缘检测
cv.pyrMeanShiftFiltering(img, 10, 100),没有执行canny边缘检测