📄 savedatafile.m
字号:
%SAVEDATAFILE Save datafile
%
% B = SAVEDATAFILE(A,FEATSIZE,NAME,NBITS,FILESIZE)
%
% INPUT
% A Datafile, or cell array with datafiles and/or datasets
% FEATSIZE Feature size, i.e. image size of a single object in B
% NAME Desired name of directory
% NBITS # of bits in case of rescaling (8,16 or 32)
% Default: no rescaling
% FILESIZE # of elements stored in a single file
% Default 10000000.
%
% OUTPUT
% B New datafile
%
% The datafile A is completed by desired preprocessing and postprocessing.
% It is saved in the directory NAME and B refers to it. If desired the
% data and target fields are compressed (after appropriate rescaling)
% to NBITS unsigned integers. The stored datafile can be retrieved by
%
% B = DATAFILE(NAME)
%
% B is a 'mature' datafile, i.e. a dataset distributed over a number of
% files. This has only advantages over a 'raw' datafile defined for a
% directory of images in case of substantial pre- and postprocessing, due
% to the overhead of the dataset construct of B.
% Default FILESIZE = 1000000.
%
% If A is cell array with datafiles and/or datasets, they are first
% horizontally concatenated before the datafile is written. The first
% element in A should be a datafile.
%
% SEE ALSO DATAFILES, DATASETS
% Copyright: R.P.W. Duin, r.p.w.duin@prtools.org
% Faculty EWI, Delft University of Technology
% P.O. Box 5031, 2600 GA Delft, The Netherlands
function c = savedatafile(dfile_in,featsize,dirr,nbits,filesize)
prtrace(mfilename,1);
if iscell(dfile_in)
b = dfile_in{1};
[m,k] = size(b);
for j=2:length(dfile_in(:))
if size(dfile_in{j},1) ~= m
error('Datafiles or datasets to be combined should have equal number of objects')
end
k = k+size(dfile_in{j},2);
end
else
b = dfile_in;
[m,k] = size(b);
end
isvaldfile(b);
c = b;
if nargin < 5 % maximum nr of elements in datafile
filesize = 1000000;
end
if nargin < 4 | isempty(nbits) % default: no conversion
nbits = 0;
end
if nargin < 3 | isempty(dirr) % invent name if not supplied
name = getname(b);
if ~isempty(name) & length(name) > 10
name = [deblank(name(1:10)) '_'];
else
name = 'PRDatafile_';
end
dirr = [name num2str(round(rand*100000))]; % make it unique
dirr = fullfile(pwd,dirr); %DXD store it in the working dir
end
if all(nbits ~= [0 1 8 16 32])
error('Illegal number of bits supplied for conversion')
end
if nargin < 2, featsize = []; end
% reorder datafile for faster retrieval
if isdatafile(b) & ~iscell(dfile_in)
file_index = getident(b.dataset,'file_index');
[jj,R] = sort(file_index(:,1)+file_index(:,2)/(max(file_index(:,2),[],1)+1));
b = b(R,:);
end
%[m,k] = size(b);
nobj= floor(filesize/k); % # of objects per file
if nobj<1
error('Filesize is too small. A single object does not even fit in!');
end
nfiles = ceil(m/nobj); % # of files needed
if exist(dirr) == 7 % if datafile already exists
act_dir = pwd;
cd(dirr); % go to it
fclose('all');
delete *.mat % make it empty
delete file*
cd(act_dir) % return to original directory
else % otherwise create it
mkdir(dirr);
end
obj1 = 1; % initialise start object
obj2 = min(obj1+nobj-1,m); % initialise end object
file_index = zeros(m,2);
len1 = prprogress([],'Saving %4i datafiles: ',nfiles);
len2 = prprogress([],'%4i: ',0);
spaces = ' ';
% initialise structure with file information
cfiles = struct('name',cell(1,nfiles),'nbits',[], ...
'offsetd',[],'scaled',[],'offsett',[],'scalet',[]);
for j=1:nfiles % run over all files to be created
closemess([],len2)
len2 = prprogress([],'%4i: ',j);
a = dataset(b(obj1:obj2,:)); % convert objects for a single file into dataset
if iscell(dfile_in)
for i=2:length(dfile_in(:))
a = [a dataset(dfile_in{i}(obj1:obj2,:))];
end
end
if ~isempty(featsize)
if prod(featsize) ~= getfeatsize(a)
error('Desired feature size does not match size of data')
else
a = setfeatsize(a,featsize);
end
end
lendata = size(a,2);
[a,scaled,offsetd,scalet,offsett,prec] = convert(a,nbits); % convert precision
filej = ['file',num2str(j)];
fname = fullfile(dirr,filej);
fid = fopen(fname,'w');
if fid<0
error('Unable to write file %s.',fname);
end
fwrite(fid,[a.data a.targets]',prec); % store
fclose(fid);
cfiles(j).name = filej; % name of the file
cfiles(j).prec = prec; % precision
cfiles(j).scaled = scaled; % scaling for datafield
cfiles(j).offsetd = offsetd; % offset for datafield
cfiles(j).scalet = scalet; % scaling for target field
cfiles(j).offsett = offsett; % offset for target field
cfiles(j).sized = a.featsize; % feature (image) size
cfiles(j).sizet = size(a.targets,2); % size target field
% create file_index
file_index(obj1:obj2,1) = repmat(j,obj2-obj1+1,1);
file_index(obj1:obj2,2) = [1:obj2-obj1+1]';
obj1 = obj2+1; % update start object
obj2 = min(obj1+nobj-1,m); % update end object
closemess([],len2)
len2 = prprogress([],'%4i',j);
end
% finalise datafile definition
c.files = cfiles; % file information
c.type = 'mature'; % mature datafile
preproc.preproc = [];
preproc.pars = {};
c.preproc = preproc; % no preprocessing
c.postproc = mapping([]); % default postprocessing
featsize = getfeatsize(a); % copy feature (image) size
c.postproc = setsize_in(c.postproc,featsize); % set input and ...
c.postproc = setsize_out(c.postproc,featsize); % output size postprocessing
c.dataset = setfeatsize(c.dataset,getfeatsize(a)); % set size datafile
c.dataset = setident(c.dataset,file_index,'file_index'); % store file_index
%DXD give it the name of the directory, not the complete path:
%c.dataset = setname(c.dataset,dirr);
[pname,dname] = fileparts(dirr);
c.dataset = setname(c.dataset,dname);
%DXD this path/filename is *very* strange!
%save(fullfile(pwd,dirr,dirr),'c'); % store the datafile as mat-file for fast retrieval
%DXD I changed it into this:
%save(fullfile(dirr,filej),'c'); % store the datafile as mat-file for fast retrieval
%RD Sorry David, I think this is better
save(fullfile(dirr,dirr),'c'); % store the datafile as mat-file for fast retrieval
closemess([],len1+len2);
return
function [a,scaled,offsetd,scalet,offsett,prec] = convert(a,nbits)
% handle precision data and target fields
if nbits == 0 % no conversion
scaled = [];
offsetd = [];
scalet = [];
offsett = [];
prec = 'double';
return;
end
% compute data field conversion pars
data = +a;
maxd = max(max(data));
mind = min(min(data));
scaled = (2^nbits)/(maxd-mind);
offsetd = -mind;
data = (data+offsetd)*scaled;
% compute target field conversion pars
targ = gettargets(a);
if isempty(targ) % no targets set
scalet = [];
offsett = [];
else
maxt = max(max(targ));
mint = min(min(targ));
scalet = (2^nbits)/(maxt-mint);
offsett = -mint;
targ = (targ+offsett)*scalet;
end
% execute conversion
switch nbits
case 8
data = uint8(data);
targ = uint8(targ);
prec = 'uint8';
case 16
data = uint16(data);
targ = uint16(targ);
prec = 'uint16';
case 32
data = uint32(data);
targ = uint32(targ);
prec = 'uint32';
otherwise
error('Desired conversion type not found')
end
% store results
a.data = data;
a.targets = targ;
return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -