]> Creatis software - CreaPhase.git/blob - octave_packages/image-1.0.15/impad.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / image-1.0.15 / impad.m
1 ## Copyright (C) 2000 Teemu Ikonen
2 ##
3 ## This program is free software; you can redistribute it and/or
4 ## modify it under the terms of the GNU General Public License
5 ## as published by the Free Software Foundation; either version 2
6 ## of the License, or (at your option) any later version.
7 ##
8 ## This program is distributed in the hope that it will be useful, but
9 ## WITHOUT ANY WARRANTY; without even the implied warranty of
10 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 ## General Public License for more details.
12 ##
13 ## You should have received a copy of the GNU General Public License
14 ## along with this program; If not, see <http://www.gnu.org/licenses/>.
15
16 ## -*- texinfo -*-
17 ## @deftypefn {Function File} {} impad(@var{A}, @var{xpad}, @var{ypad}, [@var{padding}, [@var{const}]])
18 ## Pad (augment) a matrix for application of image processing algorithms.
19 ##
20 ## Pads the input image @var{A} with @var{xpad}(1) elements from left, 
21 ## @var{xpad}(2), elements from right, @var{ypad}(1) elements from above 
22 ## and @var{ypad}(2) elements from below.
23 ## Values of padding elements are determined from the optional arguments
24 ## @var{padding} and @var{const}. @var{padding} is one of
25 ##
26 ## @table @samp
27 ## @item "zeros"     
28 ## pad with zeros (default)
29 ##
30 ## @item "ones"      
31 ## pad with ones
32 ##
33 ## @item "constant"  
34 ## pad with a value obtained from the optional fifth argument const
35 ##
36 ## @item "symmetric" 
37 ## pad with values obtained from @var{A} so that the padded image mirrors 
38 ## @var{A} starting from edges of @var{A}
39 ## 
40 ## @item "reflect"   
41 ## same as symmetric, but the edge rows and columns are not used in the padding
42 ##
43 ## @item "replicate" 
44 ## pad with values obtained from A so that the padded image 
45 ## repeates itself in two dimensions
46 ## 
47 ## @end table
48 ## @end deftypefn
49
50 ## Author: Teemu Ikonen <tpikonen@pcu.helsinki.fi>
51 ## Created: 5.5.2000
52 ## Keywords: padding image processing
53
54 ## A nice test matrix for padding:
55 ## A = 10*[1:5]' * ones(1,5) + ones(5,1)*[1:5]
56
57 function retim = impad(im, xpad, ypad, padding = "zeros", const = 1)
58   ## Input checking
59   if (!ismatrix(im) || ndims(im) < 2 || ndims(im) > 3)
60     error("impad: first input argument must be an image");
61   endif
62   if (isscalar(xpad) && xpad >= 0)
63     xpad(2) = xpad;
64   elseif (!isreal(xpad) || numel(xpad) != 2 || any(xpad < 0))
65     error("impad: xpad must be a positive scalar or 2-vector");
66   endif
67   if (isscalar(ypad) && ypad >= 0)
68     ypad(2) = ypad;
69   elseif (!isreal(ypad) || numel(ypad) != 2 || any(ypad < 0))
70     error("impad: ypad must be a positive scalar or 2-vector");
71   endif
72   if (!isscalar(const))
73     error("impad: fifth input argument must be a scalar");
74   endif
75
76   origx = size(im,2);
77   origy = size(im,1);
78   retx = origx + xpad(1) + xpad(2);
79   rety = origy + ypad(1) + ypad(2);
80   cl = class(im);
81
82   for iter = size(im,3):-1:1
83     A = im(:,:,iter);
84     switch (lower(padding))
85       case "zeros"
86         retval = zeros(rety, retx, cl);
87         retval(ypad(1)+1 : ypad(1)+origy, xpad(1)+1 : xpad(1)+origx) = A;
88       case "ones"
89         retval = ones(rety, retx, cl);
90         retval(ypad(1)+1 : ypad(1)+origy, xpad(1)+1 : xpad(1)+origx) = A;
91       case "constant"
92         retval = const.*ones(rety, retx, cl);
93         retval(ypad(1)+1 : ypad(1)+origy, xpad(1)+1 : xpad(1)+origx) = A;
94       case "replicate"
95         y1 = origy-ypad(1)+1;
96         x1 = origx-xpad(1)+1;    
97         if (y1 < 1 || x1 < 1 || ypad(2) > origy || xpad(2) > origx)
98           error("impad: too large padding for this padding type");
99         else
100           yrange1 = y1:origy;
101           yrange2 = 1:ypad(2);
102           xrange1 = x1:origx;
103           xrange2 = 1:xpad(2);
104           retval = [ A(yrange1, xrange1), A(yrange1, :), A(yrange1, xrange2);
105                      A(:, xrange1),       A,             A(:, xrange2);
106                      A(yrange2, xrange1), A(yrange2, :), A(yrange2, xrange2) ];
107         endif                        
108       case "symmetric"
109         y2 = origy-ypad(2)+1;
110         x2 = origx-xpad(2)+1;
111         if (ypad(1) > origy || xpad(1) > origx || y2 < 1 || x2 < 1)
112           error("impad: too large padding for this padding type");
113         else
114           yrange1 = 1 : ypad(1);
115           yrange2 = y2 : origy;
116           xrange1 = 1 : xpad(1);
117           xrange2 = x2 : origx;
118           retval = [ fliplr(flipud(A(yrange1, xrange1))), flipud(A(yrange1, :)), fliplr(flipud(A(yrange1, xrange2)));
119                      fliplr(A(:, xrange1)), A, fliplr(A(:, xrange2));
120                      fliplr(flipud(A(yrange2, xrange1))), flipud(A(yrange2, :)), fliplr(flipud(A(yrange2, xrange2))) ];
121         endif      
122       case "reflect"
123         y2 = origy-ypad(2);
124         x2 = origx-xpad(2);
125         if (ypad(1)+1 > origy || xpad(1)+1 > origx || y2 < 1 || x2 < 1)
126           error("impad: too large padding for this padding type");
127         else
128           yrange1 = 2 : ypad(1)+1;
129           yrange2 = y2 : origy-1;
130           xrange1 = 2 : xpad(1)+1;
131           xrange2 = x2 : origx-1;
132           retval = [ fliplr(flipud(A(yrange1, xrange1))), flipud(A(yrange1, :)), fliplr(flipud(A(yrange1, xrange2)));
133                      fliplr(A(:, xrange1)), A, fliplr(A(:, xrange2));
134                      fliplr(flipud(A(yrange2, xrange1))), flipud(A(yrange2, :)), fliplr(flipud(A(yrange2, xrange2))) ];
135         endif
136       otherwise   
137         error("impad: unknown padding type");
138     endswitch
139     
140     retim(:,:,iter) = retval;
141   endfor      
142 endfunction