Search code examples
matlabmatrixoctavesubsetboundary

Get the indexes of the boundary cells of a subset of a matrix. Matlab


Given a matrix where 1 is the current subset

test =

     0     0     0     0     0     0
     0     0     0     0     0     0
     0     0     1     1     0     0
     0     0     1     1     0     0
     0     0     0     0     0     0
     0     0     0     0     0     0

Is there a function, or quick method to get change the subset to the boundary of the current subset?

Eg. Get this subset from 'test' above

test =

     0     0     0     0     0     0
     0     1     1     1     1     0
     0     1     0     0     1     0
     0     1     0     0     1     0
     0     1     1     1     1     0
     0     0     0     0     0     0

In the end I just want to get the minimum of the cells surrounding a subset of a matrix. Sure I could loop through and get the minimum of the boundary (cell by cell), but there must be a way to do it with the method i've shown above.

Note the subset WILL be connected, but may not be rectangular. This may be the big catch.

This is a possible subset.... (Would pad this with a NaN border)

test =

     0     0     0     0     0     0
     0     0     0     0     0     0
     0     0     1     1     0     0
     0     0     1     1     0     0
     0     0     1     1     1     1
     0     0     1     1     1     1

Ideas?


Solution

  • The basic steps I'd use are:

    1. Perform a dilation on the shape to get a new area which is the shape plus its boundary
    2. Subtract the original shape from the dilated shape to leave just the boundary
    3. Use the boundary to index your data matrix, then take the minimum.

    Dilation

    What I want to do here is pass a 3x3 window over each cell and take the maximum value in that window:

    [m, n] = size(A); % assuming A is your original shape matrix
    APadded = zeros(m + 2, n + 2);
    APadded(2:end-1, 2:end-1) = A; % pad A with zeroes on each side
    ADilated = zeros(m + 2, n + 2); % this will hold the dilated shape.
    
    for i = 1:m
        for j = 1:n
            mask = zeros(size(APadded));
            mask(i:i+2, j:j+2) = 1; % this places a 3x3 square of 1's around (i, j)
            ADilated(i + 1, j + 1) = max(APadded(mask));
        end
    end
    

    Shape subtraction

    This is basically a logical AND and a logical NOT to remove the intersection:

    ABoundary = ADilated & (~APadded);
    

    At this stage you may want to remove the border we added to do the dilation, since we don't need it any more.

    ABoundary = ABoundary(2:end-1, 2:end-1);
    

    Find the minimum data point along the boundary

    We can use our logical boundary to index the original data into a vector, then just take the minimum of that vector.

    dataMinimum = min(data(ABoundary));