--- /dev/null
+## Copyright (C) 2005 Carvalho-Mariel
+## Copyright (C) 2010 Carnë Draug <carandraug+dev@gmail.com>
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} @var{B} = imtophat (@var{A}, @var{se})
+## @deftypefnx{Function File} @var{B} = imtophat (@var{A}, @var{se}, @var{type})
+## Perform morphological top hat filtering.
+##
+## The image @var{A} must be a grayscale or binary image, and @var{se} must be a
+## structuring element. Both must have the same class, e.g., if @var{A} is a
+## logical matrix, @var{se} must also be logical.
+##
+## @var{type} defines the type of top hat transform. To perform a white, or
+## opening, top-hat transform its value must be @code{open} or @code{white}. To
+## perform a black, or closing, top-hat transform its value must be @code{close}
+## or @code{black}. If @var{type} is not specified, it performs a white top-hat
+## transform.
+##
+## @seealso{imerode, imdilate, imopen, imclose, mmgradm}
+## @end deftypefn
+
+function retval = imtophat(im, se, trans)
+
+ ## Checkinput
+ if (nargin <=1 || nargin > 3)
+ print_usage();
+ elseif (nargin == 2)
+ trans = "white";
+ endif
+ if (!ismatrix(im) || !isreal(im))
+ error("imtophat: first input argument must be a real matrix");
+ elseif (!ismatrix(se) || !isreal(se))
+ error("imtophat: second input argument must be a real matrix");
+ elseif ( !strcmp(class(im), class(se)) )
+ error("imtophat: image and structuring element must have the same class");
+ endif
+
+ ## Perform filtering
+ ## Note that in case that the transform is to applied to a logical image,
+ ## subtraction must be handled in a different way (x & !y) instead of (x - y)
+ ## or it will return a double precision matrix
+ if ( strcmpi(trans, "white") || strcmpi(trans, "open") )
+ if (islogical(im))
+ retval = im & !imopen(im,se);
+ else
+ retval = im - imopen(im, se);
+ endif
+ elseif ( strcmpi(trans, "black") || strcmpi(trans, "close") )
+ if (islogical(im))
+ retval = imclose(im, se) & !im;
+ else
+ retval = imclose(im, se) - im;
+ endif
+ else
+ error ("Unexpected type of top-hat transform");
+ endif
+
+endfunction
+
+%!test
+%! I = [1 1 1; 1 1 1; 1 1 1;];
+%! se = [1 1; 0 1;];
+%! ## class of input should be the same as the output
+%! result = imtophat(logical(I), logical(se));
+%! expected = 0.5 < [0 0 1; 0 0 1; 1 1 1];
+%! assert(expected, result);
+%! result = imtophat((I), (se));
+%! expected = [0 0 1; 0 0 1; 1 1 1];
+%! assert(expected, result);
+
+