Main Content

本页的翻译已过时。点击此处可查看最新英文版本。

imfindcircles

使用圆形 Hough 变换查找圆

说明

centers = imfindcircles(A,radius) 查找图像 A 中半径约等于 radius 的圆。输出 centers 是一个两列矩阵,其中包含图像中各圆中心的 (x,y) 坐标。

[centers,radii] = imfindcircles(A,radiusRange) 查找半径在 radiusRange 指定范围内的圆。附加输出参数 radii 包含与 centers 中每个圆心对应的估计半径。

示例

[centers,radii,metric] = imfindcircles(A,radiusRange) 还返回列向量 metric,其中包含每个圆的累加器数组峰值的幅值(按降序排列)。centersradii 的行对应于 metric 的行。

示例

[___] = imfindcircles(___,Name,Value) 支持任何上述语法,且可使用一个或多个 Name,Value 对组参数指定其他选项。

示例

全部折叠

此示例说明如何找到一个图像中的所有圆形,以及如何保留和显示强度最大的圆形。

将灰度图像读入工作区并显示它。

A = imread('coins.png');
imshow(A)

Figure contains an axes. The axes contains an object of type image.

查找半径为 r 个像素且在 [15, 30] 范围内的所有圆形。

[centers, radii, metric] = imfindcircles(A,[15 30]);

根据度量值保留五个强度最大的圆形。

centersStrong5 = centers(1:5,:); 
radiiStrong5 = radii(1:5);
metricStrong5 = metric(1:5);

在原始图像上绘制五个强度最大的圆周。

viscircles(centersStrong5, radiiStrong5,'EdgeColor','b');

Figure contains an axes. The axes contains 3 objects of type line, image.

将图像读入工作区中并显示它。

A = imread('circlesBrightDark.png');
imshow(A)

Figure contains an axes. The axes contains an object of type image.

定义半径范围。

Rmin = 30;
Rmax = 65;

找出图像中半径范围内的所有亮圆。

[centersBright, radiiBright] = imfindcircles(A,[Rmin Rmax],'ObjectPolarity','bright');

找出图像中半径范围内的所有暗圆。

[centersDark, radiiDark] = imfindcircles(A,[Rmin Rmax],'ObjectPolarity','dark');

在亮圆的边缘周围绘制蓝色线条。

viscircles(centersBright, radiiBright,'Color','b');

Figure contains an axes. The axes contains 3 objects of type line, image.

在暗圆的边缘周围绘制红色虚线。

viscircles(centersDark, radiiDark,'LineStyle','--');

Figure contains an axes. The axes contains 5 objects of type line, image.

输入参数

全部折叠

输入图像是在其中检测圆形目标的图像,指定为灰度图像、真彩色图像或二值图像。

数据类型: single | double | int16 | uint8 | uint16 | logical

圆半径是要检测的圆形目标的近似半径,指定为正数。

数据类型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

要检测的圆形目标的半径范围,指定为 [rmin rmax] 形式的由正整数组成的二元素向量,其中 rmin 小于 rmax

数据类型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

名称-值对组参数

指定可选的、以逗号分隔的 Name,Value 对组参数。Name 为参数名称,Value 为对应的值。Name 必须放在引号中。您可采用任意顺序指定多个名称-值对组参数,如 Name1,Value1,...,NameN,ValueN

示例: 'ObjectPolarity','bright' 在深色背景上指定亮色圆形目标。

对象极性,指定为以逗号分隔的对组,由 'ObjectPolarity' 和下表中的值之一组成。

'bright'圆形目标比背景亮。
'dark'圆形目标比背景暗。

计算方法是用于计算累加器数组的方法,指定为以逗号分隔的对组,由 'Method' 和下表中的值之一组成。

'PhaseCode'Atherton 和 Kerbyson 的 [1] 相位编码方法。这是默认设置。
'TwoStage'两阶段圆形 Hough 变换 [2][3] 中使用的方法。

示例: 'Method','PhaseCode' 指定 Atherton 和 Kerbyson 的相位编码方法。

敏感度因子是圆形 Hough 变换累加器数组的敏感度,指定为由 'Sensitivity' 和 [0,1] 范围内的数值组成的以逗号分隔的对组。随着敏感度因子的增大,imfindcircles 会检测到更多圆形目标,包括弱圆形和部分模糊圆形。更高的敏感度值也会增加错误检测的风险。

边缘梯度阈值设置用于确定图像中边缘像素的梯度阈值,指定为由 'EdgeThreshold' 和范围 [0,1] 内的数值组成的以逗号分隔的对组。指定 0 可将阈值设置为零梯度幅值。指定 1 可将阈值设置为最大梯度幅值。阈值设置得越低,imfindcircles 检测到的圆形目标(具有弱边缘和强边缘)越多。随着阈值的增大,它会检测到较少的具有弱边缘的圆形。默认情况下,imfindcircles 使用函数 graythresh 自动选择边缘梯度阈值。

示例: 'EdgeThreshold',0.5 将边缘梯度阈值设置为 0.5

输出参数

全部折叠

圆心坐标,返回为 P×2 矩阵,第一列中包含圆心的 x 坐标,第二列中包含 y 坐标。行数 P 是检测到的圆形的个数。centers 根据圆形的强度排序。

数据类型: double

各圆心对应的估计半径,以列向量形式返回。radii(j) 处的半径值对应于以 centers(j,:) 为中心的圆形。

数据类型: double

圆形的强度是各圆心对应的相对强度,以向量形式返回。metric(j) 处的值对应于以 centers(j,:) 为中心、半径为 radii(j) 的圆。

数据类型: double

提示

  • radius(或 rmin)的值小于或等于 5 时,imfindcircles 的准确度会受到限制。

  • 如果使用 'PhaseCode' 方法(默认值)而不是 'TwoStage',半径估计步骤通常会更快。

  • 'PhaseCode''TwoStage' 这两种计算方法检测同心圆的能力有限。同心圆的结果可能因输入图像而异。

  • imfindcircles 找不到圆心位于图像区域之外的圆形。

  • imfindcircles 会预处理二值(逻辑值)图像以提高结果的准确度。在处理真彩色图像之前,它使用 rgb2gray 函数将其转换为灰度图像。

算法

imfindcircles 使用基于圆形 Hough 变换 (CHT) 的算法在图像中寻找圆形。之所以使用这种方法,是因为当存在噪声、遮挡和变化的光照条件时该方法表现稳健。

CHT 并非严格指定的算法,在其实现中可采用许多不同方法。不过,总的来说,所有这些方法都有三个基本步骤。

  1. 累加器数组计算

    高梯度的前景像素指定为候选像素,并允许在累加器数组中“投票”。在经典 CHT 实现中,候选像素在围绕像素构成一个固定半径全圆的模式中投票。在图 1a 所示的示例中显示了一个实际圆(实线圆)上的候选像素以及该候选像素的经典 CHT 投票模式(虚线圆)。

    经典 CHT 投票模式

  2. 中心估计

    属于同一个图像圆的各候选像素的投票趋于在对应于该圆中心的累加器数组 bin 中累加。因此,可通过检测累加器数组中的峰值来估计圆心。在图 1b 所示的示例中显示一个实际圆(实线圆)上的各候选像素(实心点)以及它们的投票模式(虚线圆),这些模式在实际圆的中心处重合。

  3. 半径估计

    如果同一累加器数组用于多个半径值(这是 CHT 算法中的常见做法),则必须以单独的步骤来估计检测到的圆的半径。

imfindcircles 提供两种在图像中寻找圆的算法:相位编码算法(默认值)和两阶段算法。两者有一些共同的计算步骤,但也各有特色。

这两种算法共有的计算功能如下:

  • 二维累加器数组的使用

    经典 Hough 变换需要三维数组来存储多个半径的投票,这需要很大的存储空间和很长的处理时间。相位编码方法和两阶段方法都通过对所有半径都使用同一个二维累加器数组来解决此问题。虽然这样做需要额外的半径估计步骤,但总体计算负载通常较低,尤其是在处理大半径范围时。这是目前 CHT 实现中广泛采用的做法。

  • 边缘像素的使用

    整体内存要求和速度很大程度上取决于候选像素的数量。为了限制其数量,请为输入图像的梯度幅值设置阈值,以便在计票中只包括高梯度的像素。

  • 边缘方向信息的使用

    优化性能的另一种方法是限制候选像素可用的 bin 的数量。这是通过利用局部可用的边缘信息来实现的,它只允许在沿梯度方向的有限区间内投票(图 2)。

    投票模式:多个半径,沿梯度方向

rmin最小搜索半径
rmax最大搜索半径
ractual候选像素所属的圆的半径
cmin半径为 rmin 的圆心
cmax半径为 rmax 的圆心
cactual半径为 ractual 的圆心

函数 imfindcircles 使用的两种 CHT 方法在计算圆半径的方式上有根本的不同。

  • 两阶段

    利用估计的圆心和图像信息显式估计半径。该方法基于计算径向直方图 [2] [3]

  • 相位编码

    相位编码 [1] 的关键思想是在累加器数组中使用复数值,并在数组项的相位中对半径信息进行编码。边缘像素所投的票不仅包含关于可能的中心位置的信息,还包含关于与中心位置相关联的圆的半径的信息。与必须使用径向直方图显式估计半径的两阶段方法不同,在相位编码方法中,可通过简单地解码来自累加器数组中估计的中心位置的相位信息来估计半径。

兼容性注意事项

全部展开

R2019a 中的行为有变化

参考

[1] T.J Atherton, D.J. Kerbyson. "Size invariant circle detection." Image and Vision Computing. Volume 17, Number 11, 1999, pp. 795-803.

[2] H.K Yuen, .J. Princen, J. Illingworth, and J. Kittler. "Comparative study of Hough transform methods for circle finding." Image and Vision Computing. Volume 8, Number 1, 1990, pp. 71–77.

[3] E.R. Davies, Machine Vision: Theory, Algorithms, Practicalities. Chapter 10. 3rd Edition. Morgan Kauffman Publishers, 2005.

扩展功能

在 R2012a 中推出