]> Creatis software - CreaPhase.git/blob - utilities_LW/im_pad.m
Useful functions for simulations (created by LW, free to use)
[CreaPhase.git] / utilities_LW / im_pad.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, write to the Free Software
15 % ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16
17
18 % ## -*- texinfo -*-
19 % ## @deftypefn {Function File} {} im_pad(@var{A}, @var{xpad}, @var{ypad}, [@var{padding}, [@var{const}]])
20 % ## Pad (augment) a matrix for application of image processing algorithms.
21 % ##
22 % ## Pads the input image @var{A} with @var{xpad}(1) elements from left, 
23 % ## @var{xpad}(2), elements from right, @var{ypad}(1) elements from above 
24 % ## and @var{ypad}(2) elements from below.
25 % ## Values of padding elements are determined from the optional arguments
26 % ## @var{padding} and @var{const}. @var{padding} is one of
27 % ##
28 % ## @table @samp
29 % ## @item "zeros"     
30 % ## pad with zeros (default)
31 % ##
32 % ## @item "ones"      
33 % ## pad with ones
34 % ##
35 % ## @item "constant"  
36 % ## pad with a value obtained from the optional fifth argument const
37 % ##
38 % ## @item "symmetric" 
39 % ## pad with values obtained from @var{A} so that the padded image mirrors 
40 % ## @var{A} starting from edges of @var{A}
41 % ## 
42 % ## @item "reflect"   
43 % ## same as symmetric, but the edge rows and columns are not used in the padding
44 % ##
45 % ## @item "replicate" 
46 % ## pad with values obtained from A so that the padded image 
47 % ## repeates itself in two dimensions
48 % ## 
49 % ## @end table
50 % ## @end deftypefn
51
52 % ## Author: Teemu Ikonen <tpikonen@pcu.helsinki.fi>
53 % ## Created: 5.5.2000
54 % ## Keywords: padding image processing
55 % ## 2006-11-28 P. Cloetens <cloetens@esrf.fr>
56 % ## * add padding possibility 'extend'
57 % ## * rename to im_pad
58 % ## 2006-12-03 PC
59 % ## * extend with average of last value over extend_avg rows/columns
60
61 % ## A nice test matrix for padding:
62 % ## A = 10*[1:5]' * ones(1,5) + ones(5,1)*[1:5]
63
64 function retval = im_pad(A, xpad, ypad, padding, const)
65
66 try empty_list_elements_ok_save = empty_list_elements_ok;
67 catch empty_list_elements_ok_save = 0;
68 end
69 try warn_empty_list_elements_save = warn_empty_list_elements;
70 catch warn_empty_list_elements_save = 0;
71 end
72 unwind_protect
73
74 if nargin < 4 
75     padding = 'zeros'; 
76 end
77 if nargin < 5 
78     const = 1; 
79 end
80
81 extend_avg = const; %# we use the same fifth argument
82
83 origx = size(A,2);
84 origy = size(A,1);
85
86 if isscalar(xpad)
87     retx = xpad;
88     xpad(1) = ceil((retx-origx)/2);
89     xpad(2) = retx-origx-xpad(1);
90 else
91     retx = origx + xpad(1) + xpad(2);
92 end
93
94 if isscalar(ypad)
95     rety = ypad;
96     ypad(1) = ceil((rety-origy)/2);
97     ypad(2) = rety-origy-ypad(1);
98 else
99     rety = origy + ypad(1) + ypad(2);
100 end
101   
102 empty_list_elements_ok = 1;
103 warn_empty_list_elements = 0;
104
105 if(strcmp(padding, 'zeros'))
106   retval = zeros(rety,retx);
107   retval(ypad(1)+1 : ypad(1)+origy, xpad(1)+1 : xpad(1)+origx) = A;
108   elseif(strcmp(padding,'ones'))
109     retval = ones(rety,retx);
110     retval(ypad(1)+1 : ypad(1)+origy, xpad(1)+1 : xpad(1)+origx) = A;
111   elseif(strcmp(padding,'constant'))
112     retval = const.*ones(rety,retx);
113     retval(ypad(1)+1 : ypad(1)+origy, xpad(1)+1 : xpad(1)+origx) = A;
114   elseif(strcmp(padding,'replicate'))
115     y1 = origy-ypad(1)+1;
116     x1 = origx-xpad(1)+1;    
117     if(y1 < 1 || x1 < 1 || ypad(2) > origy || xpad(2) > origx)
118       error('Too large padding for this padding type');
119     else
120       yrange1 = y1 : origy;
121       yrange2 = 1 : ypad(2);
122       xrange1 = x1 : origx;
123       xrange2 = 1 : xpad(2);
124       retval = [ A(yrange1, xrange1), A(yrange1, :), A(yrange1, xrange2);
125                  A(:, xrange1),       A,             A(:, xrange2);
126                  A(yrange2, xrange1), A(yrange2, :), A(yrange2, xrange2) ];
127     end                        
128   elseif(strcmp(padding,'symmetric'))
129     y2 = origy-ypad(2)+1;
130     x2 = origx-xpad(2)+1;
131     if(ypad(1) > origy || xpad(1) > origx || y2 < 1 || x2 < 1)
132       error('Too large padding for this padding type');
133     else
134       yrange1 = 1 : ypad(1);
135       yrange2 = y2 : origy;
136       xrange1 = 1 : xpad(1);
137       xrange2 = x2 : origx;
138       retval = [ fliplr(flipud(A(yrange1, xrange1))), flipud(A(yrange1, :)), fliplr(flipud(A(yrange1, xrange2)));
139                  fliplr(A(:, xrange1)), A, fliplr(A(:, xrange2));
140                  fliplr(flipud(A(yrange2, xrange1))), flipud(A(yrange2, :)), fliplr(flipud(A(yrange2, xrange2))) ];
141     end      
142    elseif(strcmp(padding,'reflect'))
143     y2 = origy-ypad(2);
144     x2 = origx-xpad(2);
145     if(ypad(1)+1 > origy || xpad(1)+1 > origx || y2 < 1 || x2 < 1)
146       error('Too large padding for this padding type');
147     else
148       yrange1 = 2 : ypad(1)+1;
149       yrange2 = y2 : origy-1;
150       xrange1 = 2 : xpad(1)+1;
151       xrange2 = x2 : origx-1;
152       retval = [ fliplr(flipud(A(yrange1, xrange1))), flipud(A(yrange1, :)), fliplr(flipud(A(yrange1, xrange2)));
153                  fliplr(A(:, xrange1)), A, fliplr(A(:, xrange2));
154                  fliplr(flipud(A(yrange2, xrange1))), flipud(A(yrange2, :)), fliplr(flipud(A(yrange2, xrange2))) ];
155     end
156    elseif(strcmp(padding,'extend'))
157     if (extend_avg > 1)
158         retval = [  repmat(mean2(A(1:extend_avg,1:extend_avg)),ypad(1),xpad(1)) , repmat(mean(A(1:extend_avg,:),1),ypad(1),1) , repmat(mean2(A(1:extend_avg,end-extend_avg+1:end)),ypad(1),xpad(2)) ;
159             repmat(mean(A(:,1:extend_avg),2),1,xpad(1)) , A , repmat(mean(A(:,end-extend_avg+1:end),2),1,xpad(2)) ;
160             repmat(mean2(A(end-extend_avg+1:end,1:extend_avg)),ypad(2),xpad(1)) , repmat(mean(A(end-extend_avg+1:end,:),1),ypad(2),1) , repmat(mean2(A(end-extend_avg+1:end,end-extend_avg+1:end)),ypad(2),xpad(2)) ];
161     else
162         retval = [  repmat(A(1,1),ypad(1),xpad(1)) , repmat(A(1,:),ypad(1),1) , repmat(A(1,end),ypad(1),xpad(2)) ;
163             repmat(A(:,1),1,xpad(1)) , A , repmat(A(:,end),1,xpad(2)) ;
164             repmat(A(end,1),ypad(2),xpad(1)) , repmat(A(end,:),ypad(2),1) , repmat(A(end,end),ypad(2),xpad(2)) ];
165     end
166   else    
167     error('Unknown padding type');
168   end
169
170 unwind_protect_cleanup
171     empty_list_elements_ok = empty_list_elements_ok_save;
172     warn_empty_list_elements = warn_empty_list_elements_save;
173 end_unwind_protect
174       
175       end