%BANDSEL Selection of bands from object images % % B = BANDSEL(A,J) % B = A*BANDSEL([],J) % B = A*BANDSEL(J) % % INPUT % A Dataset or datafile with multi-band object images % J Indices of bands to be selected % % OUTPUT % B Dataset with selected bands (ordered according to J) % % DESCRIPTION % If the objects in a dataset or datafile A are multi-band images, e.g. RGB % images, or the result of IM_PATCH, then the featsize of A is [M,N,L] for % for L bands of an M x N images. This routine makes a selection J out of % L. The routine BAND2OBJ may be used to organize the bands vertically % as separate objects. However, BANDSEL nor BAND2OBJ can be applied to % datafiles for which already a bandselection has been defined by BANDSEL. % % % SEE ALSO (PRTools Guide) % DATASETS, DATAFILES, IM2OBJ, IM_PATCH, 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 = bandsel(varargin) argin = shiftargin(varargin,'vector'); argin = setdefaults(argin,[],1); if mapping_task(argin,'definition') b = define_mapping(argin,'fixed'); b = setname(b,'Band Selection'); else [a,J] = deal(argin{:}); if isdatafile(a) % just store administration if size(J,1) ~= 1 if size(J,1) ~= size(a,1) error('Matrix with band indices does not match number of objects') end else J = repmat(J,size(a,1),1); end %determine number of bands to be selected if iscell(J) n = size(J{1},2); else n = size(J,2); end %store bandselection as a mapping to be executed %during dataset conversion v = prmapping(mfilename,'fixed',{[]},[],0,0); % make the mappings identical, i.e. independent of v.data % and store the data in the ident field under 'bandsel'. % This will enable vertical concatenation of datafiles J0 = getident(a,'bandsel'); J1 = zeros(size(J)); if ~isempty(J0) % we already have a bandselection set; change it if size(J,1) == 1 J1 = J0(:,J); else for j=1:size(J0,1) J1(j,:) = J0(j,J(j,:)); end end else J1 = J; end %correct bandnames in ident a = setident(a,J1,'bandsel'); bandnames = getident(a,'bandnames'); if ~isempty(bandnames) for j=1:size(a,1) bandnames{j} = bandnames{j}(J(j,:),:); end a = setident(a,bandnames,'bandnames'); end v = setdata(v,[]); b = addpostproc(a,v); elseif isdataset(a) % execute m = size(a,1); if isempty(J) % J is stored in a.ident.bandsel J = getident(a,'bandsel'); % we assume that new bandnames are already set, % simulataneously with bandsel if isempty(J) % no bandselection defined b = a; return end else if size(J,1) == 1 J = repmat(J(:)',m,1); else if size(J,1) ~= m error('Wrong size of band selection array') end end bandnames = getident(a,'bandnames'); if ~isempty(bandnames) for j=1:m bandnames{j} = bandnames{j}(J,:); end a = setident(a,bandnames,'bandnames'); end end isobjim(a); fsize = getfeatsize(a); if length(fsize) < 3 error('No image bands defined for dataset') end if any(J(:) > fsize(3)) id = getident(a); id = id(find(J>fsize(3))); error(['Wrong index for image bands. Object ident: ' int2str(id(1))] ) end k = prod(fsize(1:2)); % size of a band L = repmat((J(:,1)-1)*k,1,k)+repmat([1:k],m,1); % indices of band_1 per object if size(J,2) > 1 % concatenate in case of multiple band selection for j=2:size(J,2) LL = repmat((J(:,j)-1)*k,1,k)+repmat([1:k],m,1); % indices of band_j per object L = [L LL]; % indices for all bands to be selected end end adata = getdata(a); % Let us do the selection on the data bdata = zeros(m,k*size(J,2)); for i=1:m % can this be done faster? bdata(i,:) = adata(i,L(i,:)); end b = setdat(a,bdata); % store the data in a dataset with all information of a b = setident(b,[],'bandsel'); % bandselection done, avoid second in case of stacked selections b = setfeatsize(b,[fsize(1:2) size(J,2)]); else error('Illegal command') end end return