Mercurial > forge
changeset 11324:b506e83e04b2 octave-forge
imerode: deal with strel objects
* accept strel objects
* matlab compatibility, changed input check
* if image is bw (logical or not), use fastest method
* commented grayscale since it's not working
* more tests
author | carandraug |
---|---|
date | Wed, 26 Dec 2012 00:19:26 +0000 |
parents | 852bd046f230 |
children | e93db158231a |
files | main/image/NEWS main/image/inst/imerode.m |
diffstat | 2 files changed, 60 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/main/image/NEWS Tue Dec 25 23:20:32 2012 +0000 +++ b/main/image/NEWS Wed Dec 26 00:19:26 2012 +0000 @@ -20,6 +20,11 @@ ** The option to create poisson noise to an image has been added to `imnoise'. + ** With the addition of the strel class, the following functions are now able + to handle strel objects: + + imerode + Summary of important user-visible changes for image 2.0.0: -------------------------------------------------------------------
--- a/main/image/inst/imerode.m Tue Dec 25 23:20:32 2012 +0000 +++ b/main/image/inst/imerode.m Wed Dec 26 00:19:26 2012 +0000 @@ -16,50 +16,80 @@ ## this program; if not, see <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {@var{B} =} imerode (@var{A}, @var{se}) -## Perform morphological erosion on a given image. +## @deftypefn {Function File} {@var{im2} =} imerode (@var{im}, @var{se}) +## Perform morphological erosion on image. ## -## The image @var{A} must be a grayscale or binary image, and @var{se} a -## structuring element. Both must have the same class, e.g., if @var{A} is a -## logical matrix, @var{se} must also be logical. Note that the erosion -## algorithm is different for each class, being much faster for logical -## matrices. As such, if you have a binary matrix, you should use @code{logical} -## first. This will also reduce the memory usage of your code. +## The image @var{im} must be a black and white image. +## +## @var{se} is the structuring element used for the erosion. It can either be +## a matrix of 0 and 1, or a strel object. ## ## The center of @var{SE} is calculated using floor((size(@var{SE})+1)/2). ## ## Pixels outside the image are considered to be 0. ## -## @seealso{imdilate, imopen, imclose} +## @seealso{imdilate, imopen, imclose, strel} ## @end deftypefn -function retval = imerode(im, se) - ## Checkinput +## TODO: we need to get grayscale erosion working again. + +function im = imerode (im, se) + if (nargin != 2) print_usage(); endif - if (!ismatrix(im) || !isreal(im)) - error("imerode: first input argument must be a real matrix"); - elseif (!ismatrix(se) || !isreal(se)) - error("imerode: second input argument must be a real matrix"); - elseif ( !strcmp(class(im), class(se)) ) - error("imerode: image and structuring element must have the same class"); + + ## it's easier to create a strel object than to have conditions later on, + ## specially once we implement structuring element decomposition + if (! isa (se, "strel")) + se = strel ("arbitrary", se); endif - ## Perform filtering - ## If image is binary/logical, try to use filter2 (much faster) - if (islogical(im)) - thr = sum(se(:)); - retval = filter2(se,im) == thr; + cl = class (im); + if (isbw (im, "non-logical")) + se = getnhood (se); + im = filter2 (se, im) == nnz (se); + ## once we do implement getsequence for strel objects we should do: +# seq = getsequence (se); +# for ii = 1:numel (seq) +# cse = getnhood (seq(ii)); +# im = filter2 (cse, im) == nnz (cse); +# endfor + + elseif (isgray (im)) + error ("imerode: grayscale erosion not yet implemented"); + ## the following code used to do this but is incorrect (checked with ImageJ) + ## im = ordfiltn (im, 1, se, 0); else - retval = ordfiltn(im, 1, se, 0); + error("imerode: IM must be a grayscale or black and white matrix"); endif + ## we return image on same class as input + im = cast (im, cl); endfunction %!demo %! imerode(ones(5,5),ones(3,3)) %! % creates a zeros border around ones. -%!assert(imerode(eye(3),[1])==eye(3)); # using [1] as a mask returns the same value -%!assert(imerode([0,1,0;1,1,1;0,1,0],[0,0,0;0,0,1;0,1,1])==[1,0,0;0,0,0;0,0,0]); # check if it works with non-symmetric SE +%!assert (imerode (eye (3), [1]), eye (3)); # using [1] as a mask returns the same value +%!assert (imerode ([0 1 0; 1 1 1;0 1 0], [0 0 0; 0 0 1; 0 1 1]), [1 0 0; 0 0 0; 0 0 0]); + +%!shared im, se, out +%! im = [0 0 0 0 0 0 0 +%! 0 0 1 0 1 0 0 +%! 0 0 1 1 0 1 0 +%! 0 0 1 1 1 0 0 +%! 0 0 0 0 0 0 0]; +%! se = [0 0 0 +%! 0 1 0 +%! 0 1 1]; +%! out = [0 0 0 0 0 0 0 +%! 0 0 1 0 0 0 0 +%! 0 0 1 1 0 0 0 +%! 0 0 0 0 0 0 0 +%! 0 0 0 0 0 0 0]; +%!assert (imerode (im, se), out); +%!assert (imerode (logical (im), se), logical (out)); +%!assert (imerode (im, logical (se)), out); +%!assert (imerode (logical (im), logical (se)), logical (out));