I have created a simple GUI that when I press a button (SAVE), the system takes the value of some fields, calculates a certain function and saves the results in a data structure. I would like this data structure to be external to the program, that is to say it remains at the exit of Matlab and at the next opening of the program this data structure must be available and upgradable.
To do this I used a global data
variable that I save and load when needed.
The problem is that it doesn't work properly, the data
structure is filled strangely.
I show you a gif that is perhaps more explanatory:
As you can see, there is a structure within the other and not a list of elements. Why?
I would like to have a data
structure that contains n elements (where n is the number of images) and each element consists of 9 fields (name
, category
, siftOctaves
, siftLevels
, siftPeak
, siftEdge
, numFeatures
, siftFeatures
, siftDescriptors
).
This is a piece of code:
%% SAVE BUTTON
function pushSiftSave_Callback(hObject, eventdata, handles)
% hObject handle to pushSiftSave (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global data;
try
% Vector of string = name of all possible images
imgs = createListOfImages('../img/');
% Get selected image
imgName = get(handles.listbox, 'Value');
imgPath = strcat('../img/', imgs(imgName));
imgPath = imgPath{1};
I_or = imread(imgPath);
I = single(rgb2gray(I_or));
% Get some parameters enter by user
[siftOctaves, siftLevels, siftPeak, siftEdge] = takeSiftParameters(handles.editSiftOctaves, handles.editSiftLevels, handles.editSiftPeakTh, handles.editSiftEdgeTh, I_or);
% Sift function
[f, d] = vl_sift(I, 'Octaves', siftOctaves, 'Levels', siftLevels, 'PeakThresh', siftPeak, 'EdgeThresh', siftEdge);
% Number of features
perm = randperm(size(f, 2));
numFeatures = size(perm, 2);
% Check if file exists
if exist('../data/data.mat', 'file') == 2
data = load('../data/data');
else
data = struct;
end
% Insert information in data structure
data = saveSiftInformation(data, imgs, imgPath, siftOctaves, siftLevels, siftPeak, siftEdge, f, d, numFeatures);
catch
ErrorMessage = lasterr;
msgbox(ErrorMessage);
disp(ErrorMessage);
end
function [data] = saveSiftInformation(data, imgs, imgPath, siftOctaves, siftLevels, siftPeak, siftEdge, features, descriptors, numFeatures)
imgPath = imgPath(8 : end);
% Find index of image
i = find((ismember(imgs, imgPath)));
% Update data structure
data(i).name = imgPath;
data(i).category = imgPath(1 : end-6);
data(i).siftOctaves = siftOctaves;
data(i).siftLevels = siftLevels;
data(i).siftPeak = siftPeak;
data(i).siftEdge = siftEdge;
data(i).numFeatures = numFeatures;
data(i).siftFeatures = features;
data(i).siftDescriptors = descriptors;
% Save data
save('../data/data', 'data');
end
%% SAVE & QUIT BUTTON.
function pushQuit_Callback(hObject, eventdata, handles)
% hObject handle to pushQuit (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global data;
assignin('base', 'data', data);
Thanks!
The problem you're facing is generated when you load the data.mat
file.
Also, using data
as the name of variable reurned by load
contributes to generating confusion.
The instruction
data = load('../data/data')
reads the data.mat
and stores the "data" it contains in a struct named data
therefore, your struct is actually a filed
of the struct data
returned by load
.
You can test it by setting a breakpoint just after the load
call and inspecting the varialbe data
.
You can fix the problem by extracting the data
field from the structure when loading the .mat
file.
if(exist('data.mat', 'file') == 2)
% data = load('data');
tmp = load('data');
data=tmp.data
else
data = struct;
end
Hope this helps,
Qapla'