tso*_*orn 5 matlab image-processing image-segmentation
如何使用MATLAB将下图中的两个连接圆分开?我尝试过使用imerode,但这并没有给出好的结果.腐蚀不起作用,因为为了腐蚀足以分离圆圈,线条消失或变得严重.在其他起始图片中,圆和线重叠,因此隔离重叠的对象也不起作用.
图像显示标识的bwboundaries对象,每个对象绘制不同的颜色.正如你所看到的那样,两个淡蓝色圆圈相连,我想将它们分开,产生两个独立的圆圈.谢谢

我建议您使用圆形霍夫变换通过imfindcircles。但是,您需要图像处理工具箱的版本 8,该版本从 R2012a 及更高版本开始提供。如果您没有这个,那么不幸的是,这将不起作用:(...但让我们假设您确实有它。但是,如果您使用的是早于 R2012a 的东西,他/她的 Dev-iL上面的评论链接到 MATLAB 文件交换上关于此实现的一些代码,很可能是在圆形霍夫变换可用之前创建的:http ://www.mathworks.com/matlabcentral/fileexchange/9168-detect-circles-with-various -灰度图像中的半径通过霍夫变换/
这是霍夫变换的一个特例,您试图在图像中找到圆圈而不是直线。这样做的好处是,即使圆是部分完成或重叠的,您也能够找到圆。
我将拍摄您上面提供的图像并对其进行一些后期处理。我将把图像转换为二进制,并删除边框,边框是白色的,包含标题。我还将填充由此产生的任何洞,以便所有对象都填充为纯白色。执行此步骤后,还会产生一些残余量化噪声,因此我将使用一个 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));
Run Code Online (Sandbox Code Playgroud)
这是我得到的图像:

现在,应用圆形霍夫变换。其一般语法是:
[centres, radii, metric] = imfindcircles(img, [start_radius, end_radius]);
Run Code Online (Sandbox Code Playgroud)
img将是包含您的形状的二值图像,start_radius并且end_radius将是您想要找到的圆的最小和最大半径。执行圆形霍夫变换,以便找到此范围(以像素为单位)内的任何圆形。输出是:
centres:返回(x,y)检测到的每个圆的中心位置radii:每个圆的半径metric:圆的纯度的度量。值越高意味着形状更有可能是圆形,反之亦然。 我搜索了半径在 30 到 60 像素之间的圆。所以:
[centres, radii, metric] = imfindcircles(out, [30, 60]);
Run Code Online (Sandbox Code Playgroud)
plot然后我们可以通过和的组合来展示检测到的圆以及半径viscircles。所以:
imshow(out);
hold on;
plot(centres(:,1), centres(:,2), 'r*'); %// Plot centres
viscircles(centres, radii, 'EdgeColor', 'b'); %// Plot circles - Make edge blue
Run Code Online (Sandbox Code Playgroud)
结果如下:

正如您所看到的,即使重叠的圆圈朝向顶部,圆形霍夫变换也能够检测到该形状中的两个不同的圆圈。
您希望确保在执行此操作之前将对象分开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
Run Code Online (Sandbox Code Playgroud)
上面的代码可能有点难以理解,但是让我们慢慢看一下。我首先计算出我们有多少个圆,这只是看看我们检测到了多少个半径。我保留一个名为的单独数组struct_reg,它将regionprops struct为图像中的每个圆和线附加一个。我用来meshgrid确定(X,Y)包含形状的图像的坐标,以便我可以在每次迭代时在空白图像上绘制一个圆圈。为此,您只需找到相对于每个圆中心的欧几里德距离,并true仅当该位置的距离小于 时将像素设置为r。执行此操作后,您将仅创建一个圆圈并将其全部过滤掉。然后,您可以使用regionprops这个圆,将其添加到我们的circles_img数组中,该数组将仅包含圆,然后继续处理其余的圆。
至此,我们就已经保存了所有的圈子。circles_img到目前为止看起来是这样的:

您会注意到绘制的圆圈很干净,但原始图像中的实际圆圈有点锯齿状。如果我们尝试用这个干净的图像删除圆圈,您将在边界上得到一些残留像素,并且您不会完全删除圆圈本身。circles_img为了说明我的意思,如果我尝试单独删除圆圈,这就是您的图像的样子:

……不太好吧?
如果你想完全删除圆圈,那么imreconstruct可以使用该图像作为种子图像进行形态学重建,并将原始图像指定为我们正在处理的图像。形态重建的工作本质上是洪水填充。您指定种子像素和要处理的图像,其工作imreconstruct是从这些种子开始,用白色进行泛色填充,直到到达种子像素所在的对象的边界。因此:
out_circles = imreconstruct(circles_img, out);
Run Code Online (Sandbox Code Playgroud)
因此,我们得到了最终重建的圆形图像:

伟大的!现在,使用它并从原始图像中删除圆圈。完成此操作后,regionprops再次运行最终图像并将其附加到您的struct_reg变量中。显然,在执行此操作之前保存原始图像的副本:
out_copy = out;
out_copy(out_circles) = false;
struct_reg = [struct_reg; regionprops(out_copy)];
Run Code Online (Sandbox Code Playgroud)
只是为了便于讨论,这就是删除圆圈后图像的样子:

现在,我们已经分析了所有的形状。请记住,我进行了完整的regionprops通话,因为我不知道您在分析中到底想要什么......所以我决定给您一切。
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
4283 次 |
| 最近记录: |