0


OpenCV入门(十九)快速学会OpenCV 18 圆环检测

OpenCV入门(十九)快速学会OpenCV 18 圆环检测

作者:Xiou

1.霍夫圆环变换概述

霍夫变换除了用来检测直线外,也能用来检测其他几何对象。实际上,只要是能够用一个参数方程表示的对象,都适合用霍夫变换来检测。用霍夫圆变换来检测图像中的圆,与使用霍夫直线变换检测直线的原理类似。

在霍夫圆变换中,需要考虑圆半径和圆心(x坐标、y坐标)共3个参数。在OpenCV中,采用的策略是两轮筛选。第1轮筛选找出可能存在圆的位置(圆心);第2轮再根据第1轮的结果筛选出半径大小。

与用来决定是否接受直线的两个参数“接受直线的最小长度(minLineLength)”和“接受直线时允许的最大像素点间距(MaxLineGap)”类似,霍夫圆变换也有几个用于决定是否接受圆的参数:圆心间的最小距离、圆的最小半径、圆的最大半径。

在OpenCV中,实现霍夫圆变换的是函数cv2.HoughCircles(),该函数将Canny边缘检测和霍夫变换结合。其语法格式为:

        circles=cv2.HoughCircles(image,
        method,
        dp,
        minDist,
        param1,
        param2,
        minRadius,
        maxRadius)

● image:输入图像,即源图像,类型为8位的单通道灰度图像。
● method:检测方法。截止到OpenCV 4.0.0-pre版本,HOUGH_GRADIENT是唯一可用的参数值。该参数代表的是霍夫圆检测中两轮检测所使用的方法。
● dp:累计器分辨率,它是一个分割比率,用来指定图像分辨率与圆心累加器分辨率的比例。例如,如果dp=1,则输入图像和累加器具有相同的分辨率。
● minDist:圆心间的最小间距。该值被作为阈值使用,如果存在圆心间距离小于该值的多个圆,则仅有一个会被检测出来。因此,如果该值太小,则会有多个临近的圆被检测出来;如果该值太大,则可能会在检测时漏掉一些圆。
● param1:该参数是缺省的,在缺省时默认值为100。它对应的是Canny边缘检测器的高阈值(低阈值是高阈值的二分之一)。
● param2:圆心位置必须收到的投票数。只有在第1轮筛选过程中,投票数超过该值的圆,才有资格进入第2轮的筛选。因此,该值越大,检测到的圆越少;该值越小,检测到的圆越多。这个参数是缺省的,在缺省时具有默认值100。
● minRadius:圆半径的最小值,小于该值的圆不会被检测出来。该参数是缺省的,在缺省时具有默认值0,此时该参数不起作用。
● maxRadius:圆半径的最大值,大于该值的圆不会被检测出来。该参数是缺省的,在缺省时具有默认值0,此时该参数不起作用。
● circles:返回值,由圆心坐标和半径构成的numpy.ndarray。

2.代码实现

霍夫圆变换 (Hough Circle Transform) 的原理和霍夫直线变换类似. 对于一条直线, 我们可以用参数 (r, θ) 表示, 对于圆我们需要三个参数 (x, y, r), 分别代表三个参数 x 圆心, y 圆心, r, 半径。

因为霍夫圆检测对噪声比较敏感, 所以首先要对图像做中值滤波。

基于效率考虑, Opencv 中实现的霍夫变换圆检测是基于图像梯度实现, 分为两步:

1.检测变换, 发现可能的圆心;
2.基于第一步的基础上从候选圆心开始计算最佳半径大小。

代码一:

import numpy as np
import cv2

# 读取图片
image = cv2.imread("aodi.jpg")
image_gray=cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image_gray=cv2.medianBlur(image_gray,5)# 均值迁移滤波#filter = cv2.pyrMeanShiftFiltering(image, 10, 100)# 转换成灰度图#filter_gray = cv2.cvtColor(filter, cv2.COLOR_BGR2GRAY)# 霍夫曼圆圈检测
circles = cv2.HoughCircles(image_gray, cv2.HOUGH_GRADIENT,1,120, param1=100, param2=30, minRadius=0, maxRadius=0)
circles = np.uint16(np.around(circles))# 遍历for circle in circles[0,:]:
    cv2.circle(image,(circle[0], circle[1]), circle[2],(0,0,255),2)
    cv2.circle(image,(circle[0], circle[1]),2,(255,0,0),2)
cv2.imwrite('img_circles.jpg', image)
cv2.imshow('HoughCircles', image)
cv2.waitKey()
cv2.destoryALLWindows()

输出结果:

在这里插入图片描述

代码二:

import numpy as np
import cv2
from matplotlib import pyplot as plt

# 读取图片
image = cv2.imread("aodi.jpg")
image_copy = image.copy()# 均值迁移滤波filter= cv2.pyrMeanShiftFiltering(image,10,100)# 转换成灰度图
filter_gray = cv2.cvtColor(filter, cv2.COLOR_BGR2GRAY)# 霍夫曼圆圈检测
circles = cv2.HoughCircles(filter_gray, cv2.HOUGH_GRADIENT,1,20, param1=100, param2=50, minRadius=0, maxRadius=0)
circles = np.uint16(np.around(circles))# 遍历for circle in circles[0,:]:
    cv2.circle(image_copy,(circle[0], circle[1]), circle[2],(0,0,255),2)
    cv2.circle(image_copy,(circle[0], circle[1]),2,(255,0,0),2)# 图片展示
f, ax = plt.subplots(2,2, figsize=(12,12))# 子图
ax[0,0].imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
ax[0,1].imshow(cv2.cvtColor(filter, cv2.COLOR_BGR2RGB))
ax[1,0].imshow(filter_gray,"gray")
ax[1,1].imshow(cv2.cvtColor(image_copy, cv2.COLOR_BGR2RGB))# 标题
ax[0,0].set_title("original")
ax[0,1].set_title("image filter")
ax[1,0].set_title("image gray")
ax[1,1].set_title("image circle")

plt.show()# 保存结果
cv2.imwrite("map_result.jpg", image_copy)

输出结果:

在这里插入图片描述
在这里插入图片描述


本文转载自: https://blog.csdn.net/qq_41600018/article/details/129697231
版权归原作者 小幽余生不加糖 所有, 如有侵权,请联系我们删除。

“OpenCV入门(十九)快速学会OpenCV 18 圆环检测”的评论:

还没有评论