gpt4 book ai didi

matlab - 使用 MATLAB 分离图像中的两个重叠圆

转载 作者:行者123 更新时间:2023-12-02 02:20:37 26 4
gpt4 key购买 nike

如何使用 MATLAB 分离下图中两个相连的圆?我试过使用 imerode ,但这并没有给出好的结果。腐 eclipse 不起作用,因为为了腐 eclipse 足以分开圆圈,线条会消失或被破坏。在其他起始图片中,圆和线重叠,因此隔离重叠对象也不起作用。

该图像显示了由 bwboundaries 标识的对象,每个物体都涂上了不同的颜色。如您所见,两个浅蓝色圆圈连接在一起,我想将它们分开,生成两个单独的圆圈。谢谢

最佳答案

我建议您通过 imfindcircles 使用圆形霍夫变换.但是,您需要图像处理工具箱的第 8 版,该工具箱从 R2012a 版本开始提供。如果你没有这个,那么不幸的是这将不起作用:(...但让我们假设你确实拥有它。但是,如果你使用比 R2012a 更旧的东西,他/她中的 Dev-iL上面的评论链接到 MATLAB 文件交换上关于此实现的一些代码,很可能是在循环霍夫变换可用之前创建的:http://www.mathworks.com/matlabcentral/fileexchange/9168-detect-circles-with-various-radii-in-grayscale-image-via-hough-transform/

这是 Hough 变换的一个特例,您试图在图像中找到圆圈而不是线条。这样做的好处是,即使圆圈部分完成或重叠,您也可以找到圆圈。

我将拍摄您在上面提供的图像并对其进行一些后期处理。我要将图像转换为二进制,并删除包含标题的白色边框。我还将填充产生的任何孔,以便所有对象都填充为纯白色。执行此步骤后还有一些残留的量化噪声,因此我将使用 3 x 3 方形元素进行小开口。之后,我将使用 3 x 3 方形元素关闭形状,因为我看到形状中有明显的间隙。所以:

因此,直接从您发布的位置读取您的图像:

im = imread('http://s29.postimg.org/spkab8oef/image.jpg'); %// Read in the image
im_gray = im2double(rgb2gray(im)); %// Convert to grayscale, then [0,1]
out = imclearborder(im_gray > 0.6); %// Threshold using 0.6, then clear the border
out = imfill(out, 'holes'); %// Fill in the holes
out = imopen(out, strel('square', 3));
out = imclose(out, strel('square', 3));

这是我得到的图像:

enter image description here

现在,应用圆形霍夫变换。这个的一般语法是:
[centres, radii, metric] = imfindcircles(img, [start_radius, end_radius]);
img将是包含您的形状的二进制图像, start_radiusend_radius将是您要查找的圆的最小和最大半径。执行圆形霍夫变换,以便它会找到在此范围内(以像素为单位)的任何圆。输出是:
  • centres :返回 (x,y)检测到的每个圆的中心位置
  • radii :每个圆的半径
  • metric :衡量圆的纯度。较高的值意味着形状更有可能是圆形,反之亦然。

  • 我搜索了半径在 30 到 60 像素之间的圆。所以:
    [centres, radii, metric] = imfindcircles(out, [30, 60]);

    然后,我们可以通过 plot 的组合来演示检测到的圆以及半径。和 viscircles .所以:
    imshow(out);
    hold on;
    plot(centres(:,1), centres(:,2), 'r*'); %// Plot centres
    viscircles(centres, radii, 'EdgeColor', 'b'); %// Plot circles - Make edge blue

    结果如下:

    enter image description here

    如您所见,即使重叠的圆朝向顶部,圆形霍夫变换也能够检测到该形状中的两个不同的圆。

    编辑 - 2014 年 11 月 16 日

    您希望确保在执行之前将对象分开 bwboundaries .这做起来有点棘手。我能看到你这样做的唯一方法是,如果你甚至不使用 bwboundaries完全自己做。我假设在所有这些之后你会想要自己分析每个形状的属性,所以我建议你做的是遍历你拥有的每个圆圈,然后将每个圆圈放在一个新的空白图像上,做 regionprops调用该形状,然后将其附加到一个单独的数组中。您还可以通过一个单独的数组来跟踪所有的圆圈,该数组一次将一个圆圈添加到该数组中。

    完成所有圆后,您将拥有一个结构数组,其中包含您找到的所有测量圆的所有测量属性。您将使用仅包含上方圆圈的数组,然后使用这些并将它们从原始图像中删除,这样您就可以获得线条。然后你再打一个电话 regionprops在此图像上获取行的信息并将其附加到您的最终结构数组。

    这是我上面概述的程序的第一部分:
    num_circles = numel(radii); %// Get number of circles
    struct_reg = []; %// Save the shape analysis per circle / line here

    %// For creating our circle in the temporary image
    [X,Y] = meshgrid(1:size(out,2), 1:size(out,1));

    %// Storing all of our circles in this image
    circles_img = false(size(out));

    for idx = 1 : num_circles %// For each circle we have...
    %// Place our circle inside a temporary image
    r = radii(idx);
    cx = centres(idx,1); cy = centres(idx,2);
    tmp = (X - cx).^2 + (Y - cy).^2 <= r^2;

    % // Save in master circle image
    circles_img(tmp) = true;

    %// Do regionprops on this image and save
    struct_reg = [struct_reg; regionprops(tmp)];
    end

    上面的代码可能有点难以下咽,但让我们慢慢来。我首先弄清楚我们有多少个圆,这只是查看我们检测到多少半径。我保留了一个名为 struct_reg 的单独数组这将附加一个 regionprops struct对于我们图像中的每个圆圈和线条。我用 meshgrid 确定 (X,Y)坐标相对于包含我们形状的图像,以便我可以在每次迭代时在空白图像上绘制一个圆圈。为此,您只需找到相对于每个圆心的欧几里得距离,并将像素设置为 true。仅当该位置的距离小于 r 时.执行此操作后,您将只创建一个圆圈并过滤掉所有圆圈。然后您将使用 regionprops在这个圈子里,把它加到我们的 circles_img数组,它只包含圆圈,然后继续处理其余的圆圈。

    此时,我们将保存我们所有的圈子。这是什么 circles_img到目前为止看起来像:

    enter image description here

    您会注意到绘制的圆圈很干净,但原始图像中的实际圆圈有点参差不齐。如果我们试图用这张干净的图像删除圆圈,你会在边框上得到一些残留的像素,而且你不会完全删除圆圈本身。为了说明我的意思,如果我尝试使用 circles_img 删除圆圈,这就是您的图像的样子。通过它自己:

    enter image description here

    ……不好,对吧?

    如果要完全去除圆圈,则通过 imreconstruct 进行形态学重建。您可以在其中使用此图像作为种子图像,并将原始图像指定为我们正在处理的图像。形态重建的工作本质上是洪水填充。您指定种子像素、要处理的图像以及 imreconstruct 的工作来自这些种子,用白色填充,直到我们到达种子像素所在的对象的边界。因此:
    out_circles = imreconstruct(circles_img, out);

    因此,我们得到了最终重建的圆形图像:

    enter image description here

    伟大的!现在,使用它并从原始图像中删除圆圈。执行此操作后,运行 regionprops再次在此最终图像上并附加到您的 struct_reg多变的。显然,在执行此操作之前保存原始图像的副本:
    out_copy = out;
    out_copy(out_circles) = false;
    struct_reg = [struct_reg; regionprops(out_copy)];

    只是为了争论,这就是删除圆圈后的图像:

    enter image description here

    现在,我们已经分析了我们所有的形状。请记住我做了完整的 regionprops打电话是因为我不知道你在分析中到底想要什么......所以我决定给你一切。

    希望这可以帮助!

    关于matlab - 使用 MATLAB 分离图像中的两个重叠圆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26906928/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com