]> Creatis software - CreaPhase.git/blob - octave_packages/image-1.0.15/im2col.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / image-1.0.15 / im2col.m
1 ## Copyright (C) 2004 Josep Mones i Teixidor
2 ##
3 ## This program is free software; you can redistribute it and/or modify
4 ## it under the terms of the GNU General Public License as published by
5 ## the Free Software Foundation; either version 2 of the License, or
6 ## (at your option) any later version.
7 ##
8 ## This program is distributed in the hope that it will be useful,
9 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
10 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 ## GNU 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} {@var{B} = } im2col (@var{A}, [@var{m},@var{n}], @var{block_type})
18 ## @deftypefnx {Function File} {@var{B} = } im2col (@var{A}, [@var{m},@var{n}])
19 ## @deftypefnx {Function File} {@var{B} = } im2col (@var{A}, 'indexed', ...)
20 ## Rearranges image blocks into columns.
21 ##
22 ## @code{B=im2col(A, [m, n], blocktype)} rearranges blocks in @var{A}
23 ## into columns in a way that's determined by @var{block_type}, which
24 ## can take the following values:
25 ##
26 ## @table @code
27 ## @item distinct
28 ## Rearranges each distinct @var{m}-by-@var{n} block in image @var{A}
29 ## into a column of @var{B}. Blocks are scanned from left to right and
30 ## the up to bottom in @var{A}, and columns are added to @var{B} from
31 ## left to right. If @var{A}'s size is not multiple @var{m}-by-@var{n}
32 ## it is padded.
33 ## @item sliding
34 ## Rearranges any @var{m}-by-@var{n} sliding block of @var{A} in a
35 ## column of @var{B}, without any padding, so only sliding blocks which
36 ## can be built using a full @var{m}-by-@var{n} neighbourhood are taken.
37 ## In consequence, @var{B} has @var{m}*@var{n} rows and
38 ## (@var{mm}-@var{m}+1)*(@var{nn}-@var{n}+1) columns (where @var{mm} and
39 ## @var{nn} are the size of @var{A}).
40 ##
41 ## This case is thought to be used applying operations on columns of
42 ## @var{B} (for instance using sum(:)), so that result is a
43 ## 1-by-(@var{mm}-@var{m}+1)*(@var{nn}-@var{n}+1) vector, that is what
44 ## the complementary function @code{col2im} expects.
45 ## @end table
46 ##
47 ## @code{B=im2col(A,[m,n])} takes @code{distinct} as a default value for
48 ## @var{block_type}. 
49 ##
50 ## @code{B=im2col(A,'indexed',...)} will treat @var{A} as an indexed
51 ## image, so it will pad using 1 if @var{A} is double. All other cases
52 ## (incluing indexed matrices with uint8 and uint16 types and
53 ## non-indexed images) will use 0 as padding value.
54 ##
55 ## Any padding needed in 'distinct' processing will be added at right
56 ## and bottom edges of the image.
57 ##
58 ## @seealso{col2im}
59 ## @end deftypefn
60
61 ## Author:  Josep Mones i Teixidor <jmones@puntbarra.com>
62
63 function B = im2col(A, varargin)
64   if(nargin<2 || nargin>4)
65     usage("B=im2col(B [, 'indexed'], [m,n] [, block_type])");
66   endif
67
68   ## check 'indexed' presence
69   indexed=false;
70   p=1;
71   if(ischar(varargin{1}) && strcmp(varargin{1}, "indexed"))
72     if(nargin<3)
73       usage("B=im2col(B [, 'indexed'], [m,n] [, block_type])");
74     endif
75     indexed=true;
76     p+=1;
77     if(isa(A,"uint8") || isa(A,"uint16"))
78         padval=0;
79     else
80       padval=1; 
81     endif
82   else
83     padval=0;
84   endif
85
86   ## check [m,n]
87   if(!isvector(varargin{p}))
88     error("im2col: expected [m,n] but param is not a vector.");
89   endif
90   if(length(varargin{p})!=2)
91     error("im2col: expected [m,n] but param has wrong length.");
92   endif
93   m=varargin{p}(1);
94   n=varargin{p}(2);
95   p+=1;
96
97   block_type='sliding';
98   if(nargin>p)
99     ## we have block_type param
100     if(!ischar(varargin{p}))
101       error("im2col: invalid parameter block_type.");
102     endif
103     block_type=varargin{p};
104     p+=1;
105   endif
106
107   ## if we didn't have 'indexed' but had 4 parameters there's an error
108   if(nargin>p)
109       usage("B=im2col(B [, 'indexed'], [m,n] [, block_type])");
110   endif
111
112   
113   ## common checks
114   if(!ismatrix(A))
115     error("im2col: A should be a matrix (or vector).");
116   endif
117
118   switch(block_type)
119     case('distinct')
120       ## calc needed padding
121       sp=mod(-size(A)',[m;n]);
122
123       if(any(sp))
124         A=padarray(A,sp,padval,'post');
125       endif
126
127       ## iterate through all blocks
128       B=[];
129       for i=1:m:size(A,1) ## up to bottom
130         for j=1:n:size(A,2) ## left to right
131           ## TODO: check if we can horzcat([],uint8([10;11])) in a
132           ## future Octave version > 2.1.58
133           if(isempty(B))
134             B=A(i:i+m-1,j:j+n-1)(:);
135           else
136             B=horzcat(B, A(i:i+m-1,j:j+n-1)(:));
137           endif
138         endfor
139       endfor
140       
141     case('sliding')
142       if(indexed)
143         disp("WARNING: 'indexed' has no sense when using sliding.");
144       endif
145       if(m>size(A,1) || n>size(A,2))
146         error("im2col: block size can't be greater than image size in sliding");
147       endif
148       ## TODO: check if matlab uses top-down and left-right order
149       B=[];
150       for j=1:1:size(A,2)-n+1 ## left to right
151         for i=1:1:size(A,1)-m+1 ## up to bottom
152           ## TODO: check if we can horzcat([],uint8([10;11])) in a
153           ## future Octave version > 2.1.58
154           if(isempty(B))
155             B=A(i:i+m-1,j:j+n-1)(:);
156           else
157             B=horzcat(B, A(i:i+m-1,j:j+n-1)(:));
158           endif
159         endfor
160       endfor
161       
162     otherwise
163       error("im2col: invalid block_type.");
164   endswitch
165
166 endfunction
167
168 %!demo
169 %! A=[1:10;11:20;21:30;31:40]
170 %! B=im2col(A,[2,5],'distinct')
171 %! C=col2im(B,[2,5],[4,10],'distinct')
172 %! # Divide A using distinct blocks and reverse operation
173
174 %!shared B, A, Bs, As, Ap, Bp0, Bp1
175 %! v=[1:10]';
176 %! r=reshape(v,2,5);
177 %! B=[v, v+10, v+20, v+30, v+40, v+50];
178 %! A=[r, r+10; r+20, r+30; r+40, r+50];
179 %! As=[1,2,3,4,5;6,7,8,9,10;11,12,13,14,15];
180 %! b1=As(1:2,1:4)(:);
181 %! b2=As(2:3,1:4)(:);
182 %! b3=As(1:2,2:5)(:);
183 %! b4=As(2:3,2:5)(:);
184 %! Bs=[b1,b2,b3,b4];
185 %! Ap=A(:,1:9);
186 %! Bp1=Bp0=B;
187 %! Bp0([9:10],[2,4,6])=0;
188 %! Bp1([9:10],[2,4,6])=1;
189
190 %!# bad block_type
191 %!error(im2col(A,[2,5],'wrong_block_type'));
192
193 %!# distinct
194 %!assert(im2col(A,[2,5],'distinct'), B);
195
196 %!# padding
197 %!assert(im2col(Ap,[2,5],'distinct'), Bp0);
198 %!assert(im2col(Ap,'indexed',[2,5],'distinct'), Bp1);
199
200 %!# now sliding
201 %!assert(im2col(As,[2,4]), Bs);
202 %!assert(im2col(As,[2,4],'sliding'), Bs);
203 %!assert(im2col(As,[3,5],'sliding'), As(:));
204
205 %!# disctint uint8 & uint16
206 %!assert(im2col(uint8(A),[2,5],'distinct'), uint8(B));
207 %!assert(im2col(uint16(A),[2,5],'distinct'), uint16(B));
208
209 %!# padding uint8 & uint16 (to 0 even in indexed case)
210 %!assert(im2col(uint8(Ap),[2,5],'distinct'), uint8(Bp0));
211 %!assert(im2col(uint8(Ap),'indexed',[2,5],'distinct'), uint8(Bp0));
212 %!assert(im2col(uint16(Ap),[2,5],'distinct'), uint16(Bp0));
213 %!assert(im2col(uint16(Ap),'indexed',[2,5],'distinct'), uint16(Bp0));
214
215 %!# now sliding uint8 & uint16
216 %!assert(im2col(uint8(As),[2,4],'sliding'), uint8(Bs));
217 %!assert(im2col(uint16(As),[2,4],'sliding'), uint16(Bs));
218
219
220
221
222 %
223 % $Log$
224 % Revision 1.4  2007/03/23 16:14:36  adb014
225 % Update the FSF address
226 %
227 % Revision 1.3  2007/01/04 23:47:43  hauberg
228 % Put seealso before end deftypefn
229 %
230 % Revision 1.2  2007/01/04 23:37:54  hauberg
231 % Minor changes in help text
232 %
233 % Revision 1.1  2006/08/20 12:59:33  hauberg
234 % Changed the structure to match the package system
235 %
236 % Revision 1.3  2005/09/08 02:00:17  pkienzle
237 % [for Bill Denney] isstr -> ischar
238 %
239 % Revision 1.2  2004/09/03 17:37:08  jmones
240 % Added support for int* and uint* types
241 %
242 % Revision 1.1  2004/08/18 14:39:07  jmones
243 % im2col and col2im added
244 %
245 %