1 % ## Copyright (C) 2000 Teemu Ikonen
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.
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.
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.
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.
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
30 % ## pad with zeros (default)
36 % ## pad with a value obtained from the optional fifth argument const
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}
43 % ## same as symmetric, but the edge rows and columns are not used in the padding
45 % ## @item "replicate"
46 % ## pad with values obtained from A so that the padded image
47 % ## repeates itself in two dimensions
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
59 % ## * extend with average of last value over extend_avg rows/columns
61 % ## A nice test matrix for padding:
62 % ## A = 10*[1:5]' * ones(1,5) + ones(5,1)*[1:5]
64 function retval = im_pad(A, xpad, ypad, padding, const)
66 try empty_list_elements_ok_save = empty_list_elements_ok;
67 catch empty_list_elements_ok_save = 0;
69 try warn_empty_list_elements_save = warn_empty_list_elements;
70 catch warn_empty_list_elements_save = 0;
81 extend_avg = const; %# we use the same fifth argument
88 xpad(1) = ceil((retx-origx)/2);
89 xpad(2) = retx-origx-xpad(1);
91 retx = origx + xpad(1) + xpad(2);
96 ypad(1) = ceil((rety-origy)/2);
97 ypad(2) = rety-origy-ypad(1);
99 rety = origy + ypad(1) + ypad(2);
102 empty_list_elements_ok = 1;
103 warn_empty_list_elements = 0;
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');
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) ];
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');
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))) ];
142 elseif(strcmp(padding,'reflect'))
145 if(ypad(1)+1 > origy || xpad(1)+1 > origx || y2 < 1 || x2 < 1)
146 error('Too large padding for this padding type');
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))) ];
156 elseif(strcmp(padding,'extend'))
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)) ];
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)) ];
167 error('Unknown padding type');
170 unwind_protect_cleanup
171 empty_list_elements_ok = empty_list_elements_ok_save;
172 warn_empty_list_elements = warn_empty_list_elements_save;