Shew
Shew

Reputation: 1596

Get the adjacent indexes from the linear indexing in matlab

Given a set of linear indexes of a matrix, how can I get only the adjacent indexes from it ?. By adjacent I meant the indexes which are either on the left, right, top, bottom or diagonal position of an index.

For example, given a 4*5 matrix

B = [1 0 0 0 0;
     1 1 0 1 1;
     0 0 1 0 1;
     1 0 1 0 0;]

and the linear indices of B [1, 2, 4, 6, 11, 12, 14, 18, 19] (it corresponds to the indexes of non-zero entreies), how can I select only the one which have at least one neighbour ? In this case, my input is

[1, 2, 4, 6, 11, 12, 14, 18, 19]

I want the output to be

[1, 2, 6, 11, 12, 14, 18, 19]

as except 4, all others have neighbours in the index set.

Upvotes: 1

Views: 232

Answers (2)

Luis Mendo
Luis Mendo

Reputation: 112729

You can use 2D-convolution to compute the number of non-zero neighbours of each entry, and use that as a logical mask:

result = find(B & conv2(B~=0, [1 1 1; 1 0 1; 1 1 1], 'same'));

Upvotes: 3

hbaderts
hbaderts

Reputation: 14336

The bwconncomp function from the Image Processing Toolbox returns connected components in binary images. As your matrix is a binary image, i.e. a 2-D matrix containing zeros and ones, we can use this.

Calling the function

>> CC = bwconncomp(B);

returns a struct containing (among other fields) PixelIdxList, which is a cell array, where each element is an array of pixel indices corresponding to a specific connected component. In your case, this is:

>> CC.PixelIdxList

ans =

  1×2 cell array

    {8×1 double}    {[4]}

So you have two connected components: one consisting of 8 pixels, with indices given by CC.PixelIdxList{1}, and a second one containing 1 pixel with index 4.

As you want to remove all pixels that have no neighbors, you can check all elements of CC.PixelIdxList for their number of elements and remove all with only one elements:

>> numPixels = cellfun(@numel,CC.PixelIdxList);
>> toRemove = (numPixels == 1);

This gives us an array toRemove containing a 0 for each connected component we want to keep, and a 1 for each connected component we want to remove. Finally, you can concatenate all connected components you want to keep into a single array with

>> allIdx = CC.PixelIdxList(~tooSmall);
>> allIdx = allIdx{:};

which leaves us with the desired result

>> allIdx

allIdx =

     1
     2
     6
    11
    12
    14
    18
    19

Upvotes: 0

Related Questions