1

假设我在名为labelledImagefrom的图像中有 5 个连接的组件(标记的对象) bwlabel。如何操作labelledImage以便仅显示标记为 1 和 4 的对象,同时删除标记为 2、3 和 5 的对象。然后,如何操作原始 RGB 图像以便标记的连接组件仅显示 1 和 4。

我知道如何通过使用下面的这行代码来保留单个连接的组件。但是,我不知道如何为多个标记区域执行此操作。

作品。

connectedComponent1 = (labelledImage == 1);
imshow(connectedComponent1)

不工作。

connectedComponent1and4 = (labelledImage == [1 4]);
imshow(connectedComponent1and4)
4

2 回答 2

1

你不能那样做logical索引。最简单的方法可能是使用布尔语句来组合事物。

connectedCompoonent1and4 = labelledImage == 1 | labelledImage == 4;

一般来说,假设你有一个元素向量来表示你想保留哪些组件,你可以使用bsxfun,permuteany帮助你。像这样的东西应该工作:

components = [1 4];
connected = any(bsxfun(@eq, labelledImage, permute(components, [1 3 2])), 3);

上面的代码使用矩阵广播创建一个临时 3D 矩阵,其中每个切片i包含i向量的第 th 值,components其中包含您想要保留的所需标签。 labelledImage也在第三维中复制,因此使用的结果bsxfun会创建一个 3D 矩阵,其中每个切片分割ii您要保留的第 th 个对象。any然后,我们使用并查看第三维将所有对象组合在一起。

如果你不喜欢单行,你甚至可以使用一个简单的for循环:

components = [1 4];
connected = false(size(labelledImage, 1), size(labelledImage, 2));
for ind = 1 : numel(components)
    connected = connected | labelledImage == components(ind);
end

这将创建一个输出图像 all false,然后我们遍历要保留的组件向量中的每个值,并将这些结果附加到结果之上。最后将为您提供您想要保留的所有组件。

最后,您还可以使用ismember并确定矩阵中可以在标签矩阵和分量向量之间找到的那些值,并以这种方式简单地创建您的掩码:

connected = ismember(labelledImage, components);

现在您有了要提取的对象蒙版,要在原始图像上使用它,只需将每个通道与蒙版相乘。的另一个用途bsxfun可以为您做到这一点。假设您的 RGB 图像被调用img,只需执行以下操作:

outImg = bsxfun(@times, img, cast(connected, class(img)));

要执行逐元素乘法,您必须确保要相乘的两个矩阵具有相同的类型。我将掩码转换为与输入图像相同的类并执行乘法。

于 2016-07-21T15:37:50.097 回答
1

使用ismember.

前任:

A = randi(5,5);  % your connected component matrix
B = [1 4]        % list of components you want to keep

A =

     4     2     1     3     5
     2     4     2     5     1
     3     4     5     1     4
     1     4     1     3     5
     4     3     5     1     5


A(~ismember(A,B)) = 0

A =

     4     0     1     0     0
     0     4     0     0     1
     0     4     0     1     4
     1     4     1     0     0
     4     0     0     1     0
于 2016-07-21T15:43:36.743 回答