@[TOC](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()

输出成果:

快速学会OpenCV 18 圆环检测

代码二:

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)

输出成果:

快速学会OpenCV 18 圆环检测
快速学会OpenCV 18 圆环检测