Main Content

bwmorph3

Morphological operations on binary volume

Description

example

J = bwmorph3(V,operation) applies the morphological operation specified by the string or character vector operation to the binary volume V. bwmorph3 returns the results of the operation in logical volume J.

Examples

collapse all

Load 3-D MRI volumetric data and create a binary volume. Use volshow to view the volumetric data with a gray color.

load mristack;
BW1 = mristack > 127;
cmap = [0.6 0.6 0.6];
volshow(BW1,Colormap=cmap);

To remove voxels that are set to 1 and that are also surrounded by voxels set to 0, perform the "clean" operation on the volumetric data. When determining which voxels to remove, the "clean" operation considers 26 neighboring voxels. Use volshow to view the results.

BW2 = bwmorph3(BW1,"clean");
volshow(BW2,Colormap=cmap);

For comparison, perform the "majority" operation on the volumetric data. The "majority" operation performs a similar task to the "clean" operation but only retains voxels if more than half (the majority) of the voxels in the neighborhood of the target voxel are set to 1. When determining which voxels to retain, the "majority" operation also considers 26 neighboring voxels. Use volshow to view the results.

BW3 = bwmorph3(BW1,"majority");
volshow(BW3,Colormap=cmap);

This example shows how each of the morphological operations supported by bwmorph3 works on simple volumes.

Make a 9-by-9-by-3 cuboid of 0s that contains a 3-by-3-by-3 cube of 1s at its center.

innercube = ones(3,3,3);
cube_center = padarray(innercube,[3 3],0,'both')
cube_center = 
cube_center(:,:,1) =

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


cube_center(:,:,2) =

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


cube_center(:,:,3) =

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

Turning Pixels Off with the Remove Operation

Set the center voxel of the inner cube to 0 using the 'remove' operation. This operation sets the value of any 'on' voxel completely surrounded by 'on' voxels to 'off'.

remove_center = bwmorph3(cube_center,'remove')
remove_center = 9x9x3 logical array
remove_center(:,:,1) =

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


remove_center(:,:,2) =

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


remove_center(:,:,3) =

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

Setting Pixels to On with the Fill Operation

Set the center voxel of the inner cube to 1 using the 'fill' operation. This operation sets the value of any 'off' voxel completely surrounded by 'on' voxels to 'on'.

fill_center = bwmorph3(remove_center,'fill')
fill_center = 9x9x3 logical array
fill_center(:,:,1) =

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


fill_center(:,:,2) =

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


fill_center(:,:,3) =

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

Removing Unconnected Pixels with the Clean Operation

Use the 'clean' operation to remove any stray voxels that are set to 1 but are not connected to a component in the volume. The example creates a stray voxel by setting a random voxel on the second plane to 1 and then uses the 'clean' operation to remove it.

cube_center(2,2,2) = 1
cube_center = 
cube_center(:,:,1) =

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


cube_center(:,:,2) =

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


cube_center(:,:,3) =

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

cube_cleaned = bwmorph3(cube_center,'clean')
cube_cleaned = 9x9x3 logical array
cube_cleaned(:,:,1) =

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


cube_cleaned(:,:,2) =

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


cube_cleaned(:,:,3) =

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

Finding the Majority

Find the majority of the cube_center using the 'majority' operation. This operation retains a voxel only if more than half (the majority) of the voxels in the 26-connected neighborhood around the voxel are set to 1.

cube_major = bwmorph3(cube_center,'majority')
cube_major = 9x9x3 logical array
cube_major(:,:,1) =

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


cube_major(:,:,2) =

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


cube_major(:,:,3) =

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

Creating a Shape Similar to a Skeleton

To illustrate the branch points and end points options, create another small matrix, this time with a linear shape, like a skeleton.

x1 = eye(5);
x2 = zeros(5);
x2(3,3) = 1;
x3 = x2;
shape = cat(3,x1,x2,x3)
shape = 
shape(:,:,1) =

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


shape(:,:,2) =

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


shape(:,:,3) =

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

Finding End Points

Find the end points of the shape using the 'endpoints' operation. The shape has three end points, one at each end of the diagonal in the first plane and one at the end of the line through the center, on the third plane.

shape_endpts = bwmorph3(shape,'endpoints')
shape_endpts = 5x5x3 logical array
shape_endpts(:,:,1) =

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


shape_endpts(:,:,2) =

   0   0   0   0   0
   0   0   0   0   0
   0   0   0   0   0
   0   0   0   0   0
   0   0   0   0   0


shape_endpts(:,:,3) =

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

Finding Branch Points

Find the branch points of the shape using the 'branchpoints' operation. The shape has a single branch point, where the diagonal line and the horizontal line meet.

shape_brpts = bwmorph3(shape,'branchpoints')
shape_brpts = 5x5x3 logical array
shape_brpts(:,:,1) =

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


shape_brpts(:,:,2) =

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


shape_brpts(:,:,3) =

   0   0   0   0   0
   0   0   0   0   0
   0   0   0   0   0
   0   0   0   0   0
   0   0   0   0   0

Input Arguments

collapse all

Input volume, specified as a numeric or logical array. For numeric input, any nonzero pixels are considered to be 1 (true).

bwmorph3 accepts 1-D, 2-D, or 3-D arrays. If you specify 1-D or 2-D input arrays, then bwmorph3 performs the morphological operation as defined for a 3-D volume. If you want 2-D behavior, use bwmorph instead.

Data Types: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | logical

Morphological operation to perform, specified as one of the following character vectors or string scalar. For examples of these operations, see Illustrations of Morphological Operations.

Operation

Description

Illustration

'branchpoints'

Find branch points of skeleton. Branch points are the voxels at the junction where multiple branches meet.

To find branch points, the image must be skeletonized. To create a skeletonized image, use bwskel.

'clean'

Remove isolated voxels, setting them to 0. An isolated voxel is an individual, 26-connected voxel that is set to 1 that are surrounded by voxels set to 0.

'endpoints'

Find end points of skeleton. End points are voxels at the ends of branches.

Note: To find end points, the image must be skeletonized. To create a skeletonized image, use bwskel.

'fill'

Fill isolated interior voxels, setting them to 1. Isolated interior voxels are individual voxels that are set to 0 that are surrounded (6-connected) by voxels set to 1.

'majority'

Keep a voxel set to 1 if 14 or more voxels (the majority) in its 3-by-3-by-3, 26-connected neighborhood are set to 1; otherwise, set the voxel to 0.

See Illustrations of Morphological Operations.

'remove'

Remove interior voxels, setting it to 0. Interior voxels are individual voxels that are set to 1 that are surrounded (6-connected) by voxels set to 1.

Data Types: char | string

Output Arguments

collapse all

Volume after morphological operations, returned as a logical array of the same size as input volume V.

Tips

  • To perform the morphological operations erosion or dilation on 3-D volumes, use the imerode or imdilate functions, specifying the structuring element ones(3,3,3).

  • To perform morphological closing, opening, top-hat filtering, or bottom-hat filtering on 3-D volumes, use the imclose, imopen, imtophat, or imbothat functions, specifying the structuring element ones(3,3,3).

Extended Capabilities

Version History

Introduced in R2018a

expand all