ECG-Kit 1.0
(5,969 bytes)
%IM_PATCH Fixed mapping or generating patches from images
%
% B = IM_PATCH(A,PSIZE,PNUM,TYPE)
% B = IM_PATCH(A,PSIZE,COORD,'user')
% B = A*IM_PATCH([],PSIZE,PNUM,TYPE)
% B = A*IM_PATCH(PSIZE,PNUM,TYPE)
%
% INPUT
% A Dataset or datafile with (multi-band) object images dataset
% PSIZE 2-dimensional patch size. If PSIZE is a scalar, square patches
% of size PSIZE x PSIZE are generated. In case PSIZE < 1, it is
% taken relative to the images size. In this case patches may
% become non-square for non-square images. Default 3 x 3.
% PNUM Number of patches, see TYPE, default 1.
% COORD Given set of N x 2 image coordinates of patch centra. This may
% be given either in pixels (ANY(COORD > 1) or relative to the
% image size (ALL(COORD <= 1).
% TYPE 'syst': systematic sampling generating PNUM x PNUM patches.
% 'rand': generation of a random set of PNUM patches.
% 'user': user defined patch positions, see COORD.
% Default: 'syst'.
%
% OUTPUT
% B Resulting dataset or datafile with the same number of objects
% as in A. Single images are replaced by the patches.
%
% DESCRIPTION
% The object images (including their N bands) are sampled and windows of size
% PSIZE are generated, replacing the original image object. They are stored
% as [PSIZE(1) PSIZE(2) NUM*N] image objects, in which N is the original
% number of bands and NUM is either PNUM (for TYPE is 'rand' or 'user') or
% PNUM x PNUM (for TYPE is 'syst').
%
% By BAND2OBJ(B,N) individual patches can be transformed into objects.
%
% EXAMPLES
% b = im_patch(a,0.5) % generate just the central parts of the images
% b = im_patch(a,[3 5],2) % generates 4 patches of size 3x5 in centra of
% % the four quadrants
% b = im_patch(a,0.1,10,'rand') % generate at random positions 10 patches
% %each with a linear size of 0.1 of the image size.
%
% SEE ALSO (<a href="http://37steps.com/prtools">PRTools Guide</a>)
% DATASETS, DATAFILES, BAND2OBJ
% Copyright: R.P.W. Duin, r.p.w.duin@37steps.com
% Faculty EWI, Delft University of Technology
% P.O. Box 5031, 2600 GA Delft, The Netherlands
function b = im_patch(varargin)
argin = shiftargin(varargin,'vector');
argin = setdefaults(argin,[],[3 3],1,'syst',[]);
if mapping_task(argin,'definition')
b = define_mapping(argin,'fixed');
b = setname(b,'Image patches');
else
[a,psize,pnum,option,N] = deal(argin{:});
if isa(a,'prdataset') % allows datafiles too
isobjim(a);
if strcmp(option,'rand')
pnum = rand(pnum,2); % generate desired number of points
option = 'user';
end
b = filtim(a,mfilename,{psize,pnum,option},0);
else % here we have a single image
a = double(a);
asize = size(a);
if length(psize) == 1, psize = [psize psize]; end
if all(psize < 1), psize = psize.*asize; end
% user want to know how many patches
if ~isempty(N) & N == 0 % this is just a hack, could be smarter
if strcmp(option,'syst')
if length(pnum) == 1, npatches = pnum*pnum;
else npatches = prod(pnum);
end
elseif strcmp(option,'user'), npatches = size(pnum,1);
elseif strcmp(option,'random'), npatches = pnum;
else error('Unknown option');
end
b = npatches;
return
end
rsize = round(psize);
if strcmp(option,'syst')
if length(pnum) == 1, pnum = [pnum pnum]; end
if isempty(N)
patches = zeros(rsize(1),rsize(2),pnum(1)*pnum(2));
else
patches = zeros(rsize(1),rsize(2),length(N));
end
for i=1:2
if pnum(i)*psize(i) <= asize(i)
%s(i) = asize(i)/(2*pnum(i))-psize(i)/2+0.5;
s(i) = asize(i)/(2*pnum(i))-psize(i)/2+1;
d(i) = asize(i)/pnum(i);
else
%s(i) = 0.5;
s(i) = 1;
d(i) = (asize(i)-psize(i))/(pnum(i)-1);
end
end
if isempty(N)
for j2 = 1:pnum(2)
for j1 = 1:pnum(1)
disp(size(a))
disp(round(s(1)+(j1-1)*d(1)))
disp(round(s(1)+(j1-1)*d(1))+rsize(1)-1)
disp(round(s(2)+(j2-1)*d(2)))
disp(round(s(2)+(j2-1)*d(2))+rsize(2)-1)
aa = a(round(s(1)+(j1-1)*d(1)):round(s(1)+(j1-1)*d(1))+rsize(1)-1, ...
round(s(2)+(j2-1)*d(2)):round(s(2)+(j2-1)*d(2))+rsize(2)-1);
patches(:,:,(j2-1)*pnum(1)+j1) = aa;
end
end
else
for n = 1:length(N)
j2 = floor((N(n)-1)/pnum(1))+1;
j1 = N(n) - pnum(1)*(j2-1);
aa = a(round(s(1)+(j1-1)*d(1)):round(s(1)+(j1-1)*d(1))+rsize(1)-1, ...
round(s(2)+(j2-1)*d(2)):round(s(2)+(j2-1)*d(2))+rsize(2)-1);
patches(:,:,n) = aa;
end
end
elseif strcmp(option,'rand')
locs = rand(pnum,2);
if ~isempty(N)
locs = locs(N,2);
end
patches = feval(mfilename,a,psize,locs,option);
elseif strcmp(option,'user')
locs = pnum;
if ~isempty(N)
locs = locs(N,:);
end
pnum = size(locs,1);
patches = zeros(rsize(1),rsize(2),pnum);
if all(locs(:) <= 1) % positions given as relative coordinates
locs = locs.*repmat([asize(1)-psize(1),asize(2)-psize(2)],pnum,1);
locs = locs + repmat([0.5 0.5],pnum,1);
end
border = max(ceil(rsize/2));
a = bord(a,NaN,border); % create mirror border to avoid problems (takes time!!)
locs = locs + border;
for j = 1:pnum
s = round(locs(j,:)-psize/2);
patches(:,:,j) = a(s(1):s(1)+rsize(1)-1,s(2):s(2)+rsize(2)-1);
end
end
b = patches;
end
end
return