1## Copyright (C) 2008 Søren Hauberg <soren@hauberg.org> 2## 3## This program is free software; you can redistribute it and/or modify it under 4## the terms of the GNU General Public License as published by the Free Software 5## Foundation; either version 3 of the License, or (at your option) any later 6## version. 7## 8## This program is distributed in the hope that it will be useful, but WITHOUT 9## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 11## details. 12## 13## You should have received a copy of the GNU General Public License along with 14## this program; if not, see <http://www.gnu.org/licenses/>. 15 16## -*- texinfo -*- 17## @deftypefn {Function File} {} imclose (@var{img}, @var{SE}) 18## Perform morphological closing. 19## 20## The matrix @var{img} must be numeric while @var{SE} can be a: 21## @itemize @bullet 22## @item 23## strel object; 24## @item 25## array of strel objects as returned by `@@strel/getsequence'; 26## @item 27## matrix of 0's and 1's. 28## @end itemize 29## 30## The closing corresponds to a dilation followed by an erosion of @var{img}, 31## using the same @var{SE}, i.e., it is equivalent to: 32## @example 33## imerode (imdilate (img, se), se); 34## @end example 35## 36## @seealso{imdilate, imerode, imopen} 37## @end deftypefn 38 39function closed = imclose (img, se) 40 41 if (nargin != 2) 42 print_usage (); 43 elseif (! isimage (img)) 44 error("imclose: IMG must be a numeric matrix"); 45 endif 46 se = prepare_strel ("imclose", se); 47 48 ## Perform filtering 49 closed = imerode (imdilate (img, se), se); 50 51endfunction 52 53%!shared in, out 54%! in = [ 0 0 0 1 1 1 0 0 1 1 55%! 0 1 0 1 1 1 0 0 0 1 56%! 1 1 1 1 1 0 0 0 0 0 57%! 0 1 1 1 1 0 0 0 0 0 58%! 0 0 0 1 0 0 0 0 1 0 59%! 0 0 0 0 0 0 0 1 1 1 60%! 0 0 0 0 1 0 1 0 1 0 61%! 0 0 0 1 1 1 1 1 0 0 62%! 0 0 0 0 1 1 1 0 0 0 63%! 0 0 0 1 1 1 0 0 0 0]; 64%! 65%! out = [ 1 1 1 1 1 1 1 1 1 1 66%! 1 1 1 1 1 1 0 0 0 1 67%! 1 1 1 1 1 0 0 0 0 1 68%! 1 1 1 1 1 0 0 0 0 1 69%! 0 0 0 1 1 0 0 0 1 1 70%! 0 0 0 1 1 1 1 1 1 1 71%! 0 0 0 1 1 1 1 1 1 1 72%! 0 0 0 1 1 1 1 1 0 0 73%! 0 0 0 1 1 1 1 0 0 0 74%! 0 0 0 1 1 1 1 0 0 0]; 75%!assert (imclose (logical (in), ones (3)), logical (out)); 76%! 77%! out = [99 99 16 16 16 73 74 64 64 64 78%! 98 88 16 16 16 73 71 64 64 64 79%! 93 88 88 61 61 61 68 70 70 70 80%! 93 88 88 61 61 61 68 71 71 71 81%! 93 93 88 61 61 61 68 75 66 66 82%! 79 79 82 90 90 49 49 49 49 66 83%! 79 79 82 91 91 48 46 46 46 66 84%! 79 79 82 95 97 48 46 46 46 72 85%! 18 18 94 96 84 48 46 46 46 59 86%! 18 18 100 96 84 50 50 50 50 59]; 87%!assert (imclose (magic (10), ones (3)), out); 88%!assert (imclose (uint8 (magic (10)), strel ("square", 3)), uint8 (out)); 89%! 90%! ## using a se that will be decomposed in 2 pieces 91%! out =[ 99 99 88 74 74 74 74 70 70 70 92%! 98 93 88 74 74 74 74 70 70 70 93%! 93 93 88 74 74 74 74 70 70 70 94%! 93 93 88 74 74 74 74 71 71 71 95%! 93 93 88 75 75 75 75 75 75 75 96%! 93 93 90 90 90 72 72 72 72 72 97%! 93 93 91 91 91 72 72 72 72 72 98%! 93 93 93 95 97 72 72 72 72 72 99%! 94 94 94 96 97 72 72 72 72 72 100%! 100 100 100 97 97 72 72 72 72 72]; 101%!assert (imclose (magic (10), ones(5)), out); 102%! 103%! ## using a weird non-symmetric and even-size se 104%! out =[ 92 99 16 16 16 70 74 58 58 58 105%! 98 88 60 73 16 73 69 70 64 58 106%! 88 81 88 60 60 60 69 69 70 70 107%! 87 87 61 68 61 60 68 69 71 69 108%! 86 93 87 61 61 61 68 75 68 69 109%! 23 82 89 89 90 45 68 45 68 66 110%! 23 23 82 89 91 48 45 45 45 66 111%! 79 23 82 95 97 46 48 46 45 72 112%! 18 79 94 96 78 50 46 46 46 59 113%! 18 18 100 94 94 78 50 50 46 59]; 114%!assert (imclose (magic (10), [1 0 0 0; 1 1 1 0; 0 1 0 1]), out); 115