简体   繁体   中英

creating a mask matrix to identify the interface of a 3-D logical matrix in MATLAB

I have 3-D logical matrix with upper part as 0 while lower part as 1 (like using 0 to describe air and 1 to describe hilly soil). for example:

a(:,:,1)=[0,0;0,0];
a(:,:,2)=[0,1;1,0];
a(:,:,3)=[1,1;1,0];
a(:,:,4)=[1,1;1,0];
a(:,:,5)=[1,1;1,0];

the three indices of a is represented here as i ,j and k. What I wish to get is a mask matrix called a_mask to tell at fixed i and j, where the interface between 0 and 1 appears. it is straightforward using nested loops:

a_mask=zeros(size(a) );
for i = 1 : size(a,1)
    for j=1: size(a,2)
        k_ind=find( a(i,j,:)==1,1);
        a_mask(i,j,k_ind)=1;
    end
end

i will get an expected a_mask as:

a_mask(:,:,1) =
 0     0
 0     0
a_mask(:,:,2) =
 0     1
 1     0
a_mask(:,:,3) =
 1     0
 0     0
a_mask(:,:,4) =
 0     0
 0     0
a_mask(:,:,5) =
 0     0
 0     0

what i wish to achieve is to vectorize the process to create a_mask so that the speed can be increased significantly.

If I understand your code correctly, you have 2D slices and for each unique row and column, you want to identify the location of the first slice where a 1 is found. Judging from the way you are phrasing your problem, once we hit a 1 for a unique row and column, we assume that the rest of the slice at this location is a contiguous run of 1s and when we hit a 0 the next time, the remainder of the slice will be 0.

You can do this vectorized very eloquently:

a_mask = cumsum(a, 3) == 1;

This code deserve some explanation. We perform a cumulative summation on the third dimension. This means that for each unique spatial location in our matrix, we cumulative sum over each 3D column and the first time we encounter a 1 in that column, that's when we set this location to 1 as there were a bunch of zeroes that were added via the cumulative sum up until this point. Any point after this, the cumulative sum won't be 1 anymore so we use logical masking to zero out all values except for when the cumulative sum is 1, and hence we get our result.

We get:

>> a_mask

a_mask(:,:,1) =

     0     0
     0     0


a_mask(:,:,2) =

     0     1
     1     0


a_mask(:,:,3) =

     1     0
     0     0


a_mask(:,:,4) =

     0     0
     0     0


a_mask(:,:,5) =

     0     0
     0     0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM