如果你有图像处理工具箱,我也可以建议 Circular Hough Transform 到 imfindcircles。但是,这至少需要 R2012a 版本,所以如果你没有它,这将不起作用。
为了完整起见,我假设您拥有它。如果您想保持图像不变,这是一个很好的方法。如果您不知道Hough Transform 是什么,它是一种在图像中查找直线的方法。 圆形霍夫变换是一种特殊情况,旨在找到图像中的圆圈。
圆形霍夫变换的另一个优点是它能够检测图像中的部分圆形。这意味着图像中连接的那些区域,我们可以将它们检测为单独的圆圈。您如何称呼imfindcircles 的方式如下:
[centers,radii] = imfindcircles(A, radiusRange);
A 将是您的对象的二进制图像,radiusRange 是一个二元素数组,用于指定您要在图像中检测到的圆的最小和最大半径。输出是:
-
centers:N x 2 数组告诉您在图像中检测到的每个圆心的 (x,y) 坐标 - x 是列,y 是行。
-
radii:对于检测到的每个对应中心,这也给出了检测到的每个圆的半径。这是一个N x 1 数组。
imfindcircles 的其他参数可能对您有用,例如 Sensitivity。更高的灵敏度意味着它能够检测到更不均匀的圆形,例如您在图像中显示的内容。它们不是完美的圆形,但它们是圆形。默认灵敏度为 0.85。我将其设置为 0.9 以获得良好的结果。此外,在处理您的图像时,我发现半径范围从 50 像素到 150 像素。因此,我这样做了:
im = im2bw(imread('http://dennlinger.bplaced.net/t06-4.jpg'));
[centers,radii] = imfindcircles(im, [50 150], 'Sensitivity', 0.9);
第一行代码直接从 StackOverflow 读取图像。我还将其转换为logical 或纯黑白,因为您上传的图像类型为uint8。此图像存储在im。接下来,我们在我们描述的方法中调用imfindcircles。
现在,如果我们想可视化检测到的圆圈,只需使用imshow 显示您的图像,然后使用viscircles 在图像中绘制圆圈。
imshow(im);
viscircles(centers, radii, 'DrawBackgroundCircle', false);
viscircles 默认情况下在轮廓上绘制白色背景的圆圈。我想禁用此功能,因为您的图像有白色圆圈,我不想显示错误的轮廓。这就是我用上面的代码得到的:
因此,您可以从中得到centers 和radii 变量。 centers 会告诉你每个检测到的圆的中心,而radii 会告诉你每个圆的半径是多少。
现在,如果您想模拟 regionprops 正在做什么,我们可以遍历所有检测到的圆圈并将它们物理绘制到 2D 地图上,其中每个圆圈都将由 ID 号标记。因此,我们可以这样做:
[X,Y] = meshgrid(1:size(im,2), 1:size(im,1));
IDs = zeros(size(im));
for idx = 1 : numel(radii)
r = radii(idx);
cen = centers(idx,:);
loc = (X - cen(1)).^2 + (Y - cen(2)).^2 <= r^2;
IDs(loc) = idx;
end
我们首先使用meshgrid 定义一个矩形网格,并初始化一个与图像大小相同的全零 IDs 数组。接下来,对于每个圆的每对半径和中心,我们定义一个以该点为中心的圆,该圆向外延伸给定半径。然后,我们将它们用作 IDs 数组中的位置,并将其设置为该特定圆圈的唯一 ID。 IDs 的结果将类似于 bwlabel 的输出。因此,如果您想提取idx 圈子所在的位置,您可以:
cir = IDs == idx;
出于演示目的,这就是 IDs 数组在我们缩放 ID 使其适合可见性[0-255] 范围后的样子:
imshow(IDs, []);
因此,每个带有不同灰色阴影的阴影圆圈表示一个独特的圆圈,该圆圈是用imfindcircles 检测到的。
但是,某些硬币的灰色阴影可能有点模糊,因为它与背景融为一体。我们可以将其可视化的另一种方法是将不同的颜色映射应用于 IDs 数组。我们可以尝试使用cool 颜色图,颜色总数为背景的唯一圆圈数+1。因此,我们可以这样做:
cmap = cool(numel(radii) + 1);
RGB = ind2rgb(IDs, cmap);
imshow(RGB);
上面的代码将创建一个颜色映射,以便每个圆圈都映射到cool 颜色映射中的唯一颜色。下一行应用了一个映射,其中每个 ID 都与ind2rgb 的颜色相关联,我们最终显示了图像。
这是我们得到的: