Reputation: 1102
Let's say I have 5 connected components (labelled objects) in an image called labelledImage
from bwlabel
. How can I manipulate labelledImage
so that the objects that are labelled as 1 and 4 only display, while removing the objects that are labelled as 2, 3 and 5. Then, how can I manipulate the original RGB image so that the connected components that are labelled as 1 and 4 only display.
I know how to retain a single connected component by using this line of code below. However, I don't know how to do this for multiple labelled regions.
Works.
connectedComponent1 = (labelledImage == 1);
imshow(connectedComponent1)
Doesn't work.
connectedComponent1and4 = (labelledImage == [1 4]);
imshow(connectedComponent1and4)
Upvotes: 1
Views: 681
Reputation: 104493
You can't do logical
indexing that way. The simplest way is to perhaps use Boolean statements to combine things.
connectedCompoonent1and4 = labelledImage == 1 | labelledImage == 4;
In general, supposing you had a vector of elements that denote which components you want to keep, you could use bsxfun
, permute
and any
to help you with that. Something like this should work:
components = [1 4];
connected = any(bsxfun(@eq, labelledImage, permute(components, [1 3 2])), 3);
The above code uses matrix broadcasting to create a temporary 3D matrix where each slice i
contains the i
th value of the vector components
which contain the desired labels you want to keep. labelledImage
is also replicated in the third dimension so the result using bsxfun
creates a 3D matrix where each slice i
segments out the i
th object you want to keep. We then combine all of the objects together using any
and looking in the third dimension.
If you don't like one-liners, you could even use a simple for
loop:
components = [1 4];
connected = false(size(labelledImage, 1), size(labelledImage, 2));
for ind = 1 : numel(components)
connected = connected | labelledImage == components(ind);
end
This creates an output image that is all false
, then we loop through each value in the vector of components you want to keep and append those results on top of the result. The end will give you all of the components you want to keep.
Lastly, you could use also use ismember
and determine those values in your matrix that can be found between the label matrix and the components vector and simply create your mask that way:
connected = ismember(labelledImage, components);
Now that you have a mask of objects you want to extract out, to use this on the original image, simply multiply each channel with the mask. Another use of bsxfun
can do that for you. Assuming your image in RGB is called img
, simply do the following:
outImg = bsxfun(@times, img, cast(connected, class(img)));
To perform element-wise multiplication, you must ensure that both matrices that are being multiplied have the same type. I convert the mask into the same class as whatever the input image is and perform the multiplication.
Upvotes: 1
Reputation:
Use ismember
.
Ex:
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
Upvotes: 1