【问题标题】:Find outlines/ borders of label image in MATLAB在 MATLAB 中查找标签图像的轮廓/边框
【发布时间】:2011-03-10 20:59:01
【问题描述】:

我想知道是否有一种简单的方法可以将标签矩阵转换为矩阵,在该矩阵中,两个标记区域相交的任何地方都有线条,而其他地方则为零,这样您就可以基本上将区域的边界叠加在标签所在的原始图像上作为流行的 label2rgb 函数的另一种可视化替代方法生成。

我问的原因是我目前正在处理一些超像素代码,所以我有很多标记区域(500 到 5,000)。我一直在使用 rgblabel 将超像素标签转换为彩色区域,打开 hold,然后将它们显示在原始图像上,并关闭 'AlphaData' 以使它们半透明。然而,有这么多地区,这可能很难从视觉上分析,我认为简单的地区边界会更好。谢谢。

[编辑] @O_O:我已经附上了一个样本标签矩阵以及目标结果,尽管我现在对 Jonas 的第二个建议非常满意。将在第二天尝试来自 user616736 的方法。我也在这里uploaded .mat 格式的示例图像,以防其他人想尝试它们。

标签矩阵:

期望的结果:

【问题讨论】:

  • 如果可能,请提供示例图片!我无法想象你在问什么。
  • 两个答案都解决了你的问题,虽然 user616736 是我最常用的(只是因为它的行数较少,意图很明确)

标签: matlab image-processing label


【解决方案1】:

一种方法是遍历所有标签并消除除边框之外的所有标签,就像这样(其中lblImg 是您的标签矩阵)

nLabels = max(lblImg(:));
for lbl = 1:nLabels
    currenObject = lblImg == lbl; %# find pixels belonging to current label
    lblImg(imerode(currentObject,strel('disk',1))) = 0; %# mask all but the border
end

imshow(label2rgb(lblImg))

编辑

一种更快的找到边界的方法是使用标记图像的梯度

[gx,gy] = gradient(lblImg);
lblImg((gx.^2+gy.^2)==0) = 0;

imshow(label2rgb(lblImg))

【讨论】:

  • 谢谢,这就是我想要的。它只是比我想要的慢很多(在我的计算机上拍摄 3/4 MP 图像大约需要 10 秒)。我希望能够在循环中对一系列标签图像执行此操作,并在我为用户显示它们时显示它们,因此延迟使这有点麻烦。我真的希望 MATLAB 中有更多内置功能可以执行得更快。
  • 嗨,这是一个很大的改进,谢谢。我稍微更改了您的代码,以便在您的中间行之后,有一行 lblImg(lblImg>0) = 1; 使生成的边缘图像二进制。有没有办法将它与lblImg((gx.^2+gy.^2)==0) = 0; 行集成以将它们整合在一起?这是一个小细节,所以如果没有,请不要担心。再次感谢。
  • @SSilk:当然可以,你可以写lblImg = (lblImg > 0) & ((gx.^2+gy.^2)>0);
【解决方案2】:

如果您可以访问图像处理工具箱(我假设您可以访问,因为您正在处理标签矩阵),您可以使用edge 函数。这是一个简单的例子

img = imread('rice.png');
imshow(img)

rice.png 是 Matlab 的库存图像,因此您可以在您的机器上运行此代码。图像看起来像这样。

现在获取标签矩阵

bw = im2bw(img, graythresh(img)); 
cc = bwconncomp(bw);
lblMatrix = labelmatrix(cc);
imshow(lblMatrix)

lblMatrix 看起来像这样

现在我们得到标签矩阵的边缘。这里我使用了 Laplacian of Gaussian 方法,但您可以选择任何其他算法(更多信息请参阅帮助)

edgeMatrix=edges(lblMatrix,'log',0);
imshow(edgeMatrix)

这会找到所有大于0 的边,这正是您所需要的。然后,您可以在处理过程中随意操作它并覆盖在其他图形之上。在实践中,你需要一些略高于零的东西,这样你就不会得到那些小圆圈(这只是由于噪音),而只会恢复你想要的。你可以修补和调整阈值到别的东西,直到你得到它恰到好处。虽然这可以自动化,但在不知道实际问题的情况下我不能说太多。无论如何,这只是为了让您朝着正确的方向开始。

【讨论】:

  • 嗨,我已经上传了一个我正在使用的标签矩阵的样本(参见原始帖子)。不寻常的一件事是所有相邻的标记区域都彼此接壤。我还没有尝试过你的方法(很快会),但你能告诉我它是否适合我的情况吗?谢谢。
  • 当然可以。在这种情况下,您可能必须使用 'roberts' 而不是 'log'... 该命令将显示为 edgeMatrix=edges(lblMatrix,'roberts',0); 这是它的样子 i.imgur.com/yUOEe.jpg 此方法还返回一个二进制映射,因此您可以直接使用它在您的应用程序中。我建议一般使用'roberts'。我只是以头顶上的'log' 为例。
【解决方案3】:

快速跟进:

我也在 Steve Eddins 的blog 上提出了这个问题,他offered 一个非常快速的方法来找到标签图像的边缘:

region_borders = imdilate(lblImg,ones(3,3)) > imerode(lblImg,ones(3,3));

我喜欢这个选项,因为我寻找边框的主要原因是出于可视化目的,这会产生更粗的边框。此外,他的函数imoverlay 是一种方便的方式来查看您在生成标签的原始图像顶部找到的边框。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    • 1970-01-01
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多