Morphological filters


Octave implements quite a number of morphological operations. Here there are examples of almost all of them applied to the test images

orig1       orig2

Their size is 160x120. In the check board to the lower right of the first image the squares are of 4px, 2px and 1px. The small dots in the central upper part are single pixels at the horizontal positions 68, 70, 72, 75, 78, 81, 84, 87, 89 and 91.

To ease the visualization, the results of the filters are doubled with respect to their original size. Also for visualization reasons, I dare to contradict the standard convention in morphological filtering and 1 will be represented as black and 0 as white. Hence with the usual notation the images show the negative of the filter applied to the negative image.

All the filters are applied only once except skel for which it is also shown the variant with an infinite iteration because this is the idea of skeletonize. See the documentation for a short description of the meaning of each filter.

The octave code to get the following enlarged versions of the examples is listed below.


bothat1 bothat2
bothat

bridge1 bridge2
bridge

clean1 clean2
clean

close1 close2
close

diag1 diag2
diag

dilate1 dilate2
dilate

erode1 erode2
erode

fill1 fill2
fill

hbreak1 hbreak2
hbreak

majority1 majority2
majority

open1 open2
open

remove1 remove2
remove

shrink1 shrink2
shrink

skel1 skel2
skel

skeli1 skeli2
skel Inf

spur1 spur2
spur

thicken1 thicken2
thicken

thin1 thin2
thin

tophat1 tophat2
tophat




The code

This is the octave code that produces the examples:


clear all

pkg load image

% list of filters
lf = {'bothat', 'bridge', 'clean', 'close', 'diag', 'dilate', 'erode', 'fill', 'hbreak', 'majority', 'open', 'remove', 'shrink', 'skel', 'spur', 'thicken', 'thin', 'tophat'};

fn = './mf_%s%d.png';


% original images

for fnum = 1:size(lf,2)
  for k = 1:2
    name = './images/mor_op.png';
    if k==1
      name = './images/spcb.png';
    end
    
    % load image
    ima = imread( name );
    ima = im2double(ima);
    ima = (ima > 0.5);

    % apply filter
    f = lf{fnum};
    % double sized
    res = kron( ~bwmorph(~ima,f,1), ones(2) );
    imwrite( res, sprintf( fn, f,k) )
  end
end

% skeletonize Inf
ima = (im2double( imread( './images/spcb.png' ) ) > 0.5);
res = kron( ~bwmorph(~ima,'skel',Inf), ones(2) );
imwrite( res, 'mf_skeli1.png' )
ima = (im2double( imread( './images/mor_op.png' ) ) > 0.5);
res = kron( ~bwmorph(~ima,'skel',Inf), ones(2) );
imwrite( res, 'mf_skeli2.png' )