Struct contents reference from a non-struct array object.

1 view (last 30 days)
This is the code that I use ,but I get this erorr. @Please, can you help me.
f
unction model = stTrain( varargin )
% See stDemo for a full demo that include both traininga and application.
%
% Pre-trained models can be downloaded from:
% http://people.csail.mit.edu/lim/lzd_cvpr2013/st_data.tgz
%
% Please cite the following paper if you end up using the code:
% USAGE
% model = stTrain( opts )
%
% INPUTS
% opts - parameters (struct or name/value pairs)
% (1) parameters for model and data:
% .nClusters - [150] number of clusters to train with
% .nTrees - [25] number of trees in forest to train
% .radius - [17] radius of sketch token patches
% .nPos - [1000] number of positive patches per cluster
% .nNeg - [800] number of negative patches per image
% .negDist - [2] distance from closest contour defining a negative
% .minCount - [4] minimum number of training examples per node
% (2) parameters for features:
% .nCells - [5] number of self similarity cells
% .normRad - [5] normalization radius (see gradientMag)
% .normConst - [.01] normalization constant (see gradientMag)
% .nOrients - [4 4 0] number of orientations for each channel set
% .sigmas - [0 1.5 5] gaussian blur for each channel set
% .chnsSmooth - [2] radius for channel smoothing (using convTri)
% .fracFtrs - [1] fraction of features to use to train each tree
% (3) other parameters:
% .seed - [1] seed for random stream (for reproducibility)
% .modelDir - ['models/'] target directory for storing models
% .modelFnm - ['model'] model filename
% .clusterFnm - ['clusters.mat'] file containing cluster info
% .bsdsDir - ['BSR/BSDS500/data/'] location of BSDS dataset
%
% OUTPUTS
% model - trained sketch token detector w the following fields
% .trees - learned forest model struct array (see forestTrain)
% .opts - input parameters and constants
% .clusters - actual cluster centers used to learn tokens
%
% get default parameters
dfs={'nClusters',150, 'nTrees',25, 'radius',17, 'nPos',1000, 'nNeg',800,...
'negDist',2, 'minCount',4, 'nCells',5, 'normRad',5, 'normConst',0.01, ...
'nOrients',[4 4 0], 'sigmas',[0 1.5 5], 'chnsSmooth',2, 'fracFtrs',1, ...
'seed',1, 'modelDir','models/', 'modelFnm','model', ...
'clusterFnm','clusters.mat', 'bsdsDir','BSR/BSDS500/data/'};
opts = getPrmDflt(varargin,dfs,1);
% if forest exists load it and return
cd(fileparts(mfilename('fullpath')));
forestDir = [opts.modelDir '/forest/'];
forestFn = [forestDir opts.modelFnm];
if exist([forestFn '.mat'], 'file')
load([forestFn '.mat']);
return;
end
% compute constants and store in opts
nTrees=opts.nTrees;
nCells=opts.nCells;
patchSiz=opts.radius*2+1;
opts.patchSiz=patchSiz;
nChns = size(stChns(ones(2,2,3),opts),3);
opts.nChns=nChns;
opts.nChnFtrs = patchSiz*patchSiz*nChns;
opts.nSimFtrs = (nCells*nCells)*(nCells*nCells-1)/2*nChns;
opts.nTotFtrs = opts.nChnFtrs + opts.nSimFtrs;
opts.cellRad = round(patchSiz/nCells/2);
tmp=opts.cellRad*2+1;
opts.cellStep = tmp-ceil((nCells*tmp-patchSiz)/(nCells-1)); disp(opts);
assert( (nCells == 0) || (mod(nCells,2)==1 && (nCells-1)*opts.cellStep+tmp <= patchSiz ));
% generate stream for reproducibility of model
stream=RandStream('mrg32k3a','Seed',opts.seed);
% train nTrees random trees (can be trained with parfor if enough memory)
for i=1:nTrees
stTrainTree( opts, stream, i );
end
% accumulate trees and merge into final model
treeFn = [opts.modelDir '/tree/' opts.modelFnm '_tree'];
for i=1:nTrees
t=load([treeFn int2str2(i,3) '.mat'],'tree');
t=t.tree;
if (i==1)
trees=t(ones(1,nTrees));
else
trees(i)=t;
end
end
nNodes=0;
for i=1:nTrees
nNodes=max(nNodes,size(trees(i).fids,1));
end
model.thrs=zeros(nNodes,nTrees,'single');
Z=zeros(nNodes,nTrees,'uint32');
model.fids=Z;
model.child=Z;
model.count=Z;
model.depth=Z;
model.distr=zeros(nNodes,size(trees(1).distr,2),nTrees,'single');
for i=1:nTrees, tree=trees(i); nNodes1=size(tree.fids,1);
model.fids(1:nNodes1,i) = tree.fids;
model.thrs(1:nNodes1,i) = tree.thrs;
model.child(1:nNodes1,i) = tree.child;
model.distr(1:nNodes1,:,i) = tree.distr;
model.count(1:nNodes1,i) = tree.count;
model.depth(1:nNodes1,i) = tree.depth;
end
model.distr = permute(model.distr, [2 1 3]);
clusters=load(opts.clusterFnm);
clusters=clusters.clusters;
model.opts = opts;
model.clusters=clusters.clusters;
if ~exist(forestDir,'dir')
mkdir(forestDir);
end
save([forestFn '.mat'], 'model', '-v7.3');
end
function stTrainTree( opts, stream, treeInd )
% Train a single tree in forest model.
% location of ground truth
trnImgDir = [opts.bsdsDir '/images/train/'];
trnGtDir = [opts.bsdsDir '/groundTruth/train/'];
imgIds=dir([trnImgDir '*.png']);
imgIds={imgIds.name};
nImgs=length(imgIds);
for i=1:nImgs,
imgIds{i}=imgIds{i}(1:end-4);
end
% extract commonly used options
radius=opts.radius;
patchSiz=opts.patchSiz;
nChns=opts.nChns;
nTotFtrs=opts.nTotFtrs;
nClusters=opts.nClusters;
nPos=opts.nPos;
nNeg=opts.nNeg;
% finalize setup
treeDir = [opts.modelDir '/tree/'];
treeFn = [treeDir opts.modelFnm '_tree'];
if exist([treeFn int2str2(treeInd,3) '.mat'],'file')
return;
end
fprintf('\n-------------------------------------------\n');
fprintf('Training tree %d of %d\n',treeInd,opts.nTrees);
tStart=clock;
% set global stream to stream with given substream (will undo at end)
streamOrig = RandStream.getGlobalStream();
set(stream,'Substream',treeInd);
RandStream.setGlobalStream( stream );
% sample nPos positive patch locations per cluster
clstr=load(opts.clusterFnm);
clstr=clstr.clusters;
for i = 1:nClusters
if i==1
centers=[];
end
ids = find(clstr.clusterId == i);
ids = ids(randperm(length(ids),min(nPos,length(ids))));
centers = [centers; [clstr.x(ids),clstr.y(ids),clstr.imId(ids),...
clstr.clusterId(ids),clstr.gtId(ids)]]; %#ok<AGROW>
end
% collect positive and negative patches and compute features
fids=sort(randperm(nTotFtrs,round(nTotFtrs*opts.fracFtrs)));
k = size(centers,1)+nNeg*nImgs;
ftrs = zeros(k,length(fids),'single');
labels = zeros(k,1); k = 0;
tid = ticStatus('Collecting data',1,1);
for i = 1:nImgs
% get image and compute channels
gt=load([trnGtDir imgIds{i} '.mat']);
gt=gt.groundTruth;
I = imread([trnImgDir imgIds{i} '.png']);
I = imPad(I,radius,'symmetric');
chns = stChns(I,opts);
% sample positive patch locations
centers1=centers(centers(:,3)==i,:);
lbls1=centers1(:,4);
xy1=single(centers1(:,[1 2]));
%///////////////////////////////////////////////////////////////
% get image and compute channels
% sample negative patch locations
M=false(size(I,1)-2*radius,size(I,2)-2*radius);
nGt=length(gt);
for j=1:nGt
M1=gt{j}.Boundaries;
% M1=handle.gt{j}.String;
if ~isempty(M1)
M=M | M1;
end
end
M(bwdist(M)<opts.negDist)=1;
M=~M;
M([1:radius end-radius:end],:)=0;
M(:,[1:radius end-radius:end])=0;
[y,x]=find(M);
k1=min(length(y),nNeg);
rp=randperm(length(y),k1);
y=y(rp);
x=x(rp);
xy0=[x y];
lbls0=ones(k1,1)*(nClusters+1);
% crop patches
xy=[xy1; xy0];
lbls=[lbls1; lbls0];
k1=length(lbls);
ps=zeros(patchSiz,patchSiz,nChns,k1,'single');
p=patchSiz-1;
for j=1:k1
ps(:,:,:,j)=chns(xy(j,2):xy(j,2)+p,xy(j,1):xy(j,1)+p,:);
end
if(0), montage2(squeeze(ps(:,:,1,:))); drawnow; end
% compute features and store
ftrs1=[reshape(ps,[],k1)' stComputeSimFtrs(ps,opts)];
ftrs(k+1:k+k1,:) = ftrs1(:,fids);
labels(k+1:k+k1) = lbls;
k=k+k1;
tocStatus(tid,i/nImgs);
end
if k<size(ftrs,1)
ftrs=ftrs(1:k,:);
labels=labels(1:k);
end
% train sketch token classifier (random decision tree)
tree=forestTrain(ftrs,labels,'maxDepth',999);
tree.fids(tree.child>0) = fids(tree.fids(tree.child>0)+1)-1;
tree=pruneTree(tree,opts.minCount); %#ok<NASGU>
if ~exist(treeDir,'dir')
mkdir(treeDir);
end
save([treeFn int2str2(treeInd,3) '.mat'],'tree');
e=etime(clock,tStart);
fprintf('Training of tree %d complete (time=%.1fs).\n',treeInd,e);
RandStream.setGlobalStream( streamOrig );
end
function tree = pruneTree( tree, minCount )
% Prune all nodes whose count is less than minCount.
% mark all internal nodes if either child has count<=minCount
mark = [0; tree.count<=minCount];
mark = mark(tree.child+1) | mark(tree.child+2);
% list of nodes to be discarded / kept
disc=tree.child(mark);
disc=[disc; disc+1];
n=length(tree.fids);
keep=1:n;
keep(disc)=[];
% prune tree
tree.fids=tree.fids(keep);
tree.thrs=tree.thrs(keep);
tree.child=tree.child(keep);
tree.distr=tree.distr(keep,:);
tree.count=tree.count(keep);
tree.depth=tree.depth(keep);
assert(all(tree.count>minCount))
% re-index children
route=zeros(1,n);
route(keep)=1:length(keep);
tree.child(tree.child>0) = route(tree.child(tree.child>0));
end
function ftrs = stComputeSimFtrs( chns, opts )
% Compute self-similarity features.
n=opts.nCells;
if(n==0),
ftrs=[];
return;
end
nSimFtrs=opts.nSimFtrs;
nChns=opts.nChns;
m=size(chns,4);
inds = ((1:n)-(n+1)/2)*opts.cellStep+opts.radius+1;
chns=reshape(chns,opts.patchSiz,opts.patchSiz,nChns*m);
chns=convBox(chns,opts.cellRad);
chns=reshape(chns(inds,inds,:,:),n*n,nChns,m);
ftrs=zeros(nSimFtrs/nChns,nChns,m,'single');
k=0;
for i=1:n*n-1
k1=n*n-i;
ftrs(k+1:k+k1,:,:)=chns(1:end-i,:,:)-chns(i+1:end,:,:);
k=k+k1;
end
ftrs = reshape(ftrs,nSimFtrs,m)';
% % For m=1, the above should be identical to the following:
% [cids1,cids2]=computeCids(size(chns),opts); % see stDetect.m
% chns=convBox(chns,opts.cellRad); k=opts.nChnFtrs;
% cids1=cids1(k+1:end)-k+1; cids2=cids2(k+1:end)-k+1;
% ftrs=chns(cids1)-chns(cids2);
end
This is the erorr
Struct contents reference from a non-struct array object.
Error in stTrain>stTrainTree (line 225)
M1=gt{j}.Boundaries;
Error in stTrain (line 102)
stTrainTree( opts, stream, i );
  6 Comments
amal alhait
amal alhait on 28 Nov 2018
Exactly, but how I can solve this issue. I really got tired by trying and nothing works with me

Sign in to comment.

Accepted Answer

Stephen23
Stephen23 on 28 Nov 2018
Edited: Stephen23 on 28 Nov 2018
The code clearly expects the cell array groundTruth to contain a structure, which must have the fields Boundaries and String (and possibly others). Does your cell array contain any structures? No, it does not (it contains a numeric vector and a character vector).
So create your cell array to contain the structures that that code requires:
groundTruth{1} = struct('Boundaries',[0,1],'String','hello.png');
groundTruth{2} = struct('Boundaries',[3,4],'String','world.png');
...
save(..., 'groundTruth')
Better designed code would have used a non-scalar structure:
  9 Comments
Image Analyst
Image Analyst on 29 Nov 2018
Yes, just as we thought. You should not try to OR those. Why do you even want to, and how do you think that can possibly work when they are not even the same size?
Image Analyst
Image Analyst on 29 Nov 2018
Sorry, I'm not going to have time to delve into the code to debug it for you. Good luck though.

Sign in to comment.

More Answers (2)

Image Analyst
Image Analyst on 29 Nov 2018
If you do this:
s.groundTruth={'D:\Master Degree\SketchTokens\BSR\BSDS500\data\images\train\1.png',[100 73]};
save('1.mat','s');
Then it will save a structure s. Then when you do this:
gt=load('1.mat');
gt will be a structure with one field called s. To get s, you can do
s = gt.s;
Now, that s is a structure with one field and that field is a cell array with two cells. To get the structure you can do
ca = s.groundTruth; % Extract the cell array.
To get the string, you can do
str = ca{1}; % will be 'D:\Master Degree\SketchTokens\BSR\BSDS500\data\images\train\1.png'
and to get the array, you can do
vec = ca{2}; % Will be [100, 73]
You've chosen a very complicated, roundabout way of saving your variables.
  1 Comment
amal alhait
amal alhait on 29 Nov 2018
how can I solve it please,
Error using |
Matrix dimensions must agree.
Error in stTrain>stTrainTree (line 227)
M=M | M1;
Error in stTrain (line 102)
stTrainTree( opts, stream, i );

Sign in to comment.


amal alhait
amal alhait on 29 Nov 2018
Anyone can help me please to run this file without mistakes.This is my email (amal_tex2014@yahoo.com).So, I can send the images and the file

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!