如何从图像中删除连接的组件同时保留一些

How to remove connected components from an image while retaining some

假设我在来自 bwlabel 的名为 labelledImage 的图像中有 5 个连接的组件(标记的对象)。如何操作 labelledImage 使得标记为 1 和 4 的对象只显示,同时删除标记为 2、3 和 5 的对象。那么,如何操作原始 RGB 图像以便仅显示标记为 1 和 4 的连通分量。

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

有效。

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

无效。

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

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

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

一般来说,假设您有一个元素向量,表示要保留哪些组件,您可以使用 bsxfun, permute and any 来帮助您。这样的事情应该有效:

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

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

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

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

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

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

connected = ismember(labelledImage, components);

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

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

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

使用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