Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare a matrix element with its neighbours without using a loop in MATLAB?

I have a matrix in MATLAB. I want to check the 4-connected neighbours (left, right, top, bottom) for every element. If the current element is less than any of the neighbours then we set it to zero otherwise it will keep its value. It can easily be done with loop, but it is very expensive as I have thousands of these matrices.

You might recognize it as nonmaxima suppression after edge detection.

like image 474
Shan Avatar asked Feb 18 '11 14:02

Shan


2 Answers

If you have the image processing toolbox, you can do this with a morpological dilation to find local maxima and suppress all other elements.

array = magic(6); %# make some data

msk = [0 1 0;1 0 1;0 1 0]; %# make a 4-neighbour mask

%# dilation will replace the center pixel with the 
%# maximum of its neighbors
maxNeighbour = imdilate(array,msk);

%# set pix to zero if less than neighbors
array(array<maxNeighbour) = 0;

array =
    35     0     0    26     0     0
     0    32     0     0     0    25
    31     0     0     0    27     0
     0     0     0     0     0     0
    30     0    34     0     0    16
     0    36     0     0    18     0

edited to use the same data as @gnovice, and to fix the code

like image 170
Jonas Avatar answered Sep 16 '22 12:09

Jonas


One way to do this is with the function NLFILTER from the Image Processing Toolbox, which applies a given function to each M-by-N block of a matrix:

>> A = magic(6)  %# A sample matrix

A =

    35     1     6    26    19    24
     3    32     7    21    23    25
    31     9     2    22    27    20
     8    28    33    17    10    15
    30     5    34    12    14    16
     4    36    29    13    18    11

>> B = nlfilter(A,[3 3],@(b) b(5)*all(b(5) >= b([2 4 6 8])))

B =

    35     0     0    26     0     0
     0    32     0     0     0    25
    31     0     0     0    27     0
     0     0     0     0     0     0
    30     0    34     0     0    16
     0    36     0     0    18     0

The above code defines an anonymous function which uses linear indexing to get the center element of a 3-by-3 submatrix b(5) and compare it to its 4-connected neighbors b([2 4 6 8]). The value in the center element is multiplied by the logical result returned by the function ALL, which is 1 when the center element is larger than all of its nearest neighbors and 0 otherwise.

like image 33
gnovice Avatar answered Sep 17 '22 12:09

gnovice