% 图片描述符计算,开启的线程数
core = 6;
p = parpool(core);
% 并行计算的图片数
sum_batch = numel(imginds);
n_batch = sum_batch/2000;
% 第几个批次的图片
N = 1;
end_batch = 2000 * N;
start_batch = 2000 *(N-1)+1;
% 原文计算方法
parfor i=start_batch:end_batch
% totaldesctime、desccount、errorimages
% 上面三个变量在parfor运行中出现问题
%显示生成图像的描述符的进度
imgind = imginds(i);
disp(['Image ',num2str(i),' / ',num2str(numel(imginds))]);
imgfilename = rels.imgfilenames{imgind};
% get all relevant relationships in the current image
if not(isempty(inputrels))
disp('inputrels is not empty!');
% query given relationships
imgrels{i} = DatabaseRelationshipSet;
imgrels{i}.append(inputrels,inputrels.imgrelinds{i});
imgrels{i}.lockimgfilenames = true;
% filter by source and target labels
validmask = true(1,numel(imgrels{i}.id));
if not(isempty(sourcelbl)) || not(isempty(targetlbl))
if not(isempty(sourcelbl))
relind = cellind_mex(imgrels{i}.sourcelabels);
relind = [relind{:}];
imgsrclbls = [imgrels{i}.sourcelabels{:}];
validsrclbl = ismember(imgsrclbls,sourcelbl);
validsrclbl = array2cell_mex(double(validsrclbl),relind,numel(imgrels{i}.sourcelabels));
validsrclbl = cellfun(@(x) not(isempty(x)) && all(x),validsrclbl);
else
validsrclbl = true(1,numel(imgrels{i}.sourcelabels));
end
if not(isempty(targetlbl))
relind = cellind_mex(imgrels{i}.targetlabels);
relind = [relind{:}];
imgtgtlbls = [imgrels{i}.targetlabels{:}];
validtgtlbl = ismember(imgtgtlbls,targetlbl);
validtgtlbl = array2cell_mex(double(validtgtlbl),relind,numel(imgrels{i}.targetlabels));
validtgtlbl = cellfun(@(x) not(isempty(x)) && all(x),validtgtlbl);
else
validtgtlbl = true(1,numel(imgrels{i}.targetlabels));
end
validmask = validmask & validsrclbl & validtgtlbl;
end
% filter relationships where any sourcelabel == targetlabel
if options.ignoreownlabel
validinds = find(validmask);
for j=validinds
validmask(j) = validmask(j) && not(any(ismember(...
imgrels{i}.targetlabels{j},...
imgrels{i}.sourcelabels{j})));
end
end
% filter out relationships that are not labeled (if requested)
if strcmp(options.labeled,'yes')
validmask = validmask & not(isnan(imgrels{i}.id));
elseif strcmp(options.labeled,'no')
validmask = validmask & isnan(imgrels{i}.id);
elseif strcmp(options.labeled,'any')
% do nothing
else
error('Unknown labeled filter option.');
end
imgrels{i}.keepSubset(find(validmask)); %#ok
% get source and target objects for relationships that do not
needobjinds = find(isnan(imgrels{i}.descind));
imganno = ImageAnnotation.empty;
if not(isempty(needobjinds))
annofilename = ImageAnnotation.img2annofilename(imgfilename);
imganno = AnnotationImporter.importAnnotation([annopath,'/',annofilename]);
imgobjectids = [imganno.imgobjects.id];
srcobjs = cell(1,numel(imgrels{i}.id));
tgtobjs = cell(1,numel(imgrels{i}.id));
for j=needobjinds
srcobjs{j} = imganno.imgobjects(ismember(imgobjectids,imgrels{i}.sourceids{j}));
tgtobjs{j} = imganno.imgobjects(ismember(imgobjectids,imgrels{i}.targetids{j}));
end
end
else
% query all relationships to/from objects with the given labels
% disp('inputrels is empty!');
% save options.mat options;
[imgrels{i},imganno,srcobjs,tgtobjs] = findDatabaseRelationships(...
imgfilename,annopath,...
'labeled',options.labeled,...
'sourcelbl',sourcelbl,...
'targetlbl',targetlbl,...
'ignoreownlabel',options.ignoreownlabel);
imgrels{i}.lockimgfilenames = true;
end
if isempty(imgrels{i}.id)
continue;
end
% copy existing relationships to keep them (if requested)
if not(options.overwrite)
disp('run it!');
qrelinds = rels.findRelationships(...
imgrels{i}.sourceids,imgrels{i}.targetids,imgind,'exact');
hasimgrelinds = find(qrelinds>=1);
qrelinds = qrelinds(hasimgrelinds);
if not(isempty(qrelinds))
imgrels{i}.copySubset(hasimgrelinds,rels,qrelinds);
rels.deleteSubset(qrelinds);
end
end
% compute descriptors if necessary
nothasdescinds = find(isnan(imgrels{i}.descind));
if not(isempty(nothasdescinds))
imginfo = imfinfo([imgpath,'/',imgfilename]);
imgres = [imginfo.Width;imginfo.Height];
[imgmin,imgmax] = ImageAnnotation.imres2imsize(imgres);
newdescriptors = desctemplate.clone; % this also clones all settings, etc. desctemplate = varargin{3}
try
tic;
% 计算预存描述子
newdescriptors.compute(...
srcobjs(nothasdescinds),tgtobjs(nothasdescinds),...
imgmin,imgmax,imgres);
newdescsrcarea = zeros(1,numel(nothasdescinds));
newdescsrcsaliency = zeros(1,numel(nothasdescinds));
for j=1:numel(nothasdescinds)
newdescsrcarea(j) = sum([srcobjs{nothasdescinds(j)}.area]);
newdescsrcsaliency(j) = max([srcobjs{nothasdescinds(j)}.saliency]);
end
% % % % totaldesctime在并行运算中出现问题
% % % totaldesctime = totaldesctime + toc;
% % % % desccount在并行运算中出现问题
% % % desccount = desccount + numel(nothasdescinds);
% % % % 每计算一张图片,就显示每个特征的计算时间
% % % disp(['Average time: ',num2str(totaldesctime/desccount)]);
disp(['Image ',num2str(i),'计算完成'])
catch err
warning(['Error caught in image ''',imgfilename,''': ',...
err.message]);
delete(newdescriptors(isvalid(newdescriptors)));
% % % errorimages在并行计算中出现问题
% % errorimages{end+1,:} = imgfilename; %#ok
continue;
end
%%%% newdescriptor.val 存储的是计算得到的Feature,分别查看第一列和第二列的意义是什么
nnew = size(newdescriptors.val,2);
if isempty(imgrels{i}.descriptors)
imgrels{i}.descriptors = newdescriptors;
imgrels{i}.descsrcarea = newdescsrcarea;
imgrels{i}.descsrcsaliency = newdescsrcsaliency;
else
imgrels{i}.descriptors.append(newdescriptors);
imgrels{i}.descsrcarea = [imgrels{i}.descsrcarea,newdescsrcarea];
imgrels{i}.descsrcsaliency = [imgrels{i}.descsrcsaliency,newdescsrcsaliency];
delete(newdescriptors(isvalid(newdescriptors)));
end
% 观测一下这个地方descind变量是怎么变化的
% nnew是所计算得到特征值的列数
imgrels{i}.descind(nothasdescinds) = ...
size(imgrels{i}.descriptors.val,2)-nnew+1:size(imgrels{i}.descriptors.val,2);
end
delete(imganno(isvalid(imganno)));
end
% % save('D:\Descriptor_实验结果\并行计算real描述符\imgrels_1-100.mat','imgrels');
save('D:\Descriptor_实验结果\并行计算real描述符\imgrels_1-2000.mat','imgrels');
% 关闭进程池
delete(p)
% 调用函数,将分开计算的5个2000张图片的结果进行拼接
tmp = imgrels;
tmp_imgrels = contact_imgrels(tmp);
batchsize = 100;
nbatches = ceil(numel(imgrels)/batchsize);
c = 1;
for i=1:nbatches
batchset = DatabaseRelationshipSet;
for j=1:min(batchsize,numel(imgrels)-(c-1))
batchset.append(imgrels{c});
c = c + 1;
end
rels.append(batchset);
end
这是一篇论文中的方法,我尝试用并行改了一下,就可以计算,其实改动的地方并不大,matlab开启并行的方法很简单,建议大家实际上手操作,然后就可以得到自己想要的答案了。
这是我的电脑CPU,是6核12线程,所以大家上面的Core = 6的定义一定要注意根据自己的计算机相匹配,否则不能开启线程池。对了,如果图片数据库过于庞大,建议分开计算,否则内存就不够用了。一定要吸取我的血泪教训!