X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?p=CreaPhase.git;a=blobdiff_plain;f=octave_packages%2Fimage-1.0.15%2Fim2col.m;fp=octave_packages%2Fimage-1.0.15%2Fim2col.m;h=0a76fc374d6d314fa638394ef715ee1c991ce2e2;hp=0000000000000000000000000000000000000000;hb=c880e8788dfc484bf23ce13fa2787f2c6bca4863;hpb=1705066eceaaea976f010f669ce8e972f3734b05 diff --git a/octave_packages/image-1.0.15/im2col.m b/octave_packages/image-1.0.15/im2col.m new file mode 100644 index 0000000..0a76fc3 --- /dev/null +++ b/octave_packages/image-1.0.15/im2col.m @@ -0,0 +1,245 @@ +## Copyright (C) 2004 Josep Mones i Teixidor +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; If not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{B} = } im2col (@var{A}, [@var{m},@var{n}], @var{block_type}) +## @deftypefnx {Function File} {@var{B} = } im2col (@var{A}, [@var{m},@var{n}]) +## @deftypefnx {Function File} {@var{B} = } im2col (@var{A}, 'indexed', ...) +## Rearranges image blocks into columns. +## +## @code{B=im2col(A, [m, n], blocktype)} rearranges blocks in @var{A} +## into columns in a way that's determined by @var{block_type}, which +## can take the following values: +## +## @table @code +## @item distinct +## Rearranges each distinct @var{m}-by-@var{n} block in image @var{A} +## into a column of @var{B}. Blocks are scanned from left to right and +## the up to bottom in @var{A}, and columns are added to @var{B} from +## left to right. If @var{A}'s size is not multiple @var{m}-by-@var{n} +## it is padded. +## @item sliding +## Rearranges any @var{m}-by-@var{n} sliding block of @var{A} in a +## column of @var{B}, without any padding, so only sliding blocks which +## can be built using a full @var{m}-by-@var{n} neighbourhood are taken. +## In consequence, @var{B} has @var{m}*@var{n} rows and +## (@var{mm}-@var{m}+1)*(@var{nn}-@var{n}+1) columns (where @var{mm} and +## @var{nn} are the size of @var{A}). +## +## This case is thought to be used applying operations on columns of +## @var{B} (for instance using sum(:)), so that result is a +## 1-by-(@var{mm}-@var{m}+1)*(@var{nn}-@var{n}+1) vector, that is what +## the complementary function @code{col2im} expects. +## @end table +## +## @code{B=im2col(A,[m,n])} takes @code{distinct} as a default value for +## @var{block_type}. +## +## @code{B=im2col(A,'indexed',...)} will treat @var{A} as an indexed +## image, so it will pad using 1 if @var{A} is double. All other cases +## (incluing indexed matrices with uint8 and uint16 types and +## non-indexed images) will use 0 as padding value. +## +## Any padding needed in 'distinct' processing will be added at right +## and bottom edges of the image. +## +## @seealso{col2im} +## @end deftypefn + +## Author: Josep Mones i Teixidor + +function B = im2col(A, varargin) + if(nargin<2 || nargin>4) + usage("B=im2col(B [, 'indexed'], [m,n] [, block_type])"); + endif + + ## check 'indexed' presence + indexed=false; + p=1; + if(ischar(varargin{1}) && strcmp(varargin{1}, "indexed")) + if(nargin<3) + usage("B=im2col(B [, 'indexed'], [m,n] [, block_type])"); + endif + indexed=true; + p+=1; + if(isa(A,"uint8") || isa(A,"uint16")) + padval=0; + else + padval=1; + endif + else + padval=0; + endif + + ## check [m,n] + if(!isvector(varargin{p})) + error("im2col: expected [m,n] but param is not a vector."); + endif + if(length(varargin{p})!=2) + error("im2col: expected [m,n] but param has wrong length."); + endif + m=varargin{p}(1); + n=varargin{p}(2); + p+=1; + + block_type='sliding'; + if(nargin>p) + ## we have block_type param + if(!ischar(varargin{p})) + error("im2col: invalid parameter block_type."); + endif + block_type=varargin{p}; + p+=1; + endif + + ## if we didn't have 'indexed' but had 4 parameters there's an error + if(nargin>p) + usage("B=im2col(B [, 'indexed'], [m,n] [, block_type])"); + endif + + + ## common checks + if(!ismatrix(A)) + error("im2col: A should be a matrix (or vector)."); + endif + + switch(block_type) + case('distinct') + ## calc needed padding + sp=mod(-size(A)',[m;n]); + + if(any(sp)) + A=padarray(A,sp,padval,'post'); + endif + + ## iterate through all blocks + B=[]; + for i=1:m:size(A,1) ## up to bottom + for j=1:n:size(A,2) ## left to right + ## TODO: check if we can horzcat([],uint8([10;11])) in a + ## future Octave version > 2.1.58 + if(isempty(B)) + B=A(i:i+m-1,j:j+n-1)(:); + else + B=horzcat(B, A(i:i+m-1,j:j+n-1)(:)); + endif + endfor + endfor + + case('sliding') + if(indexed) + disp("WARNING: 'indexed' has no sense when using sliding."); + endif + if(m>size(A,1) || n>size(A,2)) + error("im2col: block size can't be greater than image size in sliding"); + endif + ## TODO: check if matlab uses top-down and left-right order + B=[]; + for j=1:1:size(A,2)-n+1 ## left to right + for i=1:1:size(A,1)-m+1 ## up to bottom + ## TODO: check if we can horzcat([],uint8([10;11])) in a + ## future Octave version > 2.1.58 + if(isempty(B)) + B=A(i:i+m-1,j:j+n-1)(:); + else + B=horzcat(B, A(i:i+m-1,j:j+n-1)(:)); + endif + endfor + endfor + + otherwise + error("im2col: invalid block_type."); + endswitch + +endfunction + +%!demo +%! A=[1:10;11:20;21:30;31:40] +%! B=im2col(A,[2,5],'distinct') +%! C=col2im(B,[2,5],[4,10],'distinct') +%! # Divide A using distinct blocks and reverse operation + +%!shared B, A, Bs, As, Ap, Bp0, Bp1 +%! v=[1:10]'; +%! r=reshape(v,2,5); +%! B=[v, v+10, v+20, v+30, v+40, v+50]; +%! A=[r, r+10; r+20, r+30; r+40, r+50]; +%! As=[1,2,3,4,5;6,7,8,9,10;11,12,13,14,15]; +%! b1=As(1:2,1:4)(:); +%! b2=As(2:3,1:4)(:); +%! b3=As(1:2,2:5)(:); +%! b4=As(2:3,2:5)(:); +%! Bs=[b1,b2,b3,b4]; +%! Ap=A(:,1:9); +%! Bp1=Bp0=B; +%! Bp0([9:10],[2,4,6])=0; +%! Bp1([9:10],[2,4,6])=1; + +%!# bad block_type +%!error(im2col(A,[2,5],'wrong_block_type')); + +%!# distinct +%!assert(im2col(A,[2,5],'distinct'), B); + +%!# padding +%!assert(im2col(Ap,[2,5],'distinct'), Bp0); +%!assert(im2col(Ap,'indexed',[2,5],'distinct'), Bp1); + +%!# now sliding +%!assert(im2col(As,[2,4]), Bs); +%!assert(im2col(As,[2,4],'sliding'), Bs); +%!assert(im2col(As,[3,5],'sliding'), As(:)); + +%!# disctint uint8 & uint16 +%!assert(im2col(uint8(A),[2,5],'distinct'), uint8(B)); +%!assert(im2col(uint16(A),[2,5],'distinct'), uint16(B)); + +%!# padding uint8 & uint16 (to 0 even in indexed case) +%!assert(im2col(uint8(Ap),[2,5],'distinct'), uint8(Bp0)); +%!assert(im2col(uint8(Ap),'indexed',[2,5],'distinct'), uint8(Bp0)); +%!assert(im2col(uint16(Ap),[2,5],'distinct'), uint16(Bp0)); +%!assert(im2col(uint16(Ap),'indexed',[2,5],'distinct'), uint16(Bp0)); + +%!# now sliding uint8 & uint16 +%!assert(im2col(uint8(As),[2,4],'sliding'), uint8(Bs)); +%!assert(im2col(uint16(As),[2,4],'sliding'), uint16(Bs)); + + + + +% +% $Log$ +% Revision 1.4 2007/03/23 16:14:36 adb014 +% Update the FSF address +% +% Revision 1.3 2007/01/04 23:47:43 hauberg +% Put seealso before end deftypefn +% +% Revision 1.2 2007/01/04 23:37:54 hauberg +% Minor changes in help text +% +% Revision 1.1 2006/08/20 12:59:33 hauberg +% Changed the structure to match the package system +% +% Revision 1.3 2005/09/08 02:00:17 pkienzle +% [for Bill Denney] isstr -> ischar +% +% Revision 1.2 2004/09/03 17:37:08 jmones +% Added support for int* and uint* types +% +% Revision 1.1 2004/08/18 14:39:07 jmones +% im2col and col2im added +% +%