Сохранить структуру данных в существующем.mat-файле без вложенности
Я создал простой графический интерфейс, который, когда я нажимаю кнопку (СОХРАНИТЬ), система берет значение некоторых полей, вычисляет определенную функцию и сохраняет результаты в структуре данных. Я хотел бы, чтобы эта структура данных была внешней по отношению к программе, то есть она остается на выходе из Matlab, и при следующем открытии программы эта структура данных должна быть доступной и обновляемой.
Для этого я использовал глобальный data
переменная, которую я сохраняю и загружаю при необходимости.
Проблема в том, что он не работает должным образом, data
структура заполнена странно.
Я покажу вам GIF, который может быть более объяснительным:
Как видите, внутри другого есть структура, а не список элементов. Зачем?
Я хотел бы иметь data
структура, которая содержит n элементов (где n - количество изображений), и каждый элемент состоит из 9 полей (name
, category
, siftOctaves
, siftLevels
, siftPeak
, siftEdge
, numFeatures
, siftFeatures
, siftDescriptors
).
Это кусок кода:
%% 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);
Спасибо!
2 ответа
Проблема, с которой вы сталкиваетесь, возникает при загрузке data.mat
файл.
Кроме того, используя data
как имя переменной возвращается load
способствует возникновению путаницы.
Инструкция
data = load('../data/data')
читает data.mat
и хранит "данные", содержащиеся в структуре с именем data
следовательно, ваша структура на самом деле filed
структуры data
вернулся load
,
Вы можете проверить это, установив точку останова сразу после load
позвонить и осмотреть varialbe data
,
Вы можете решить проблему, извлекая data
поле из структуры при загрузке .mat
файл.
if(exist('data.mat', 'file') == 2)
% data = load('data');
tmp = load('data');
data=tmp.data
else
data = struct;
end
Надеюсь это поможет,
Qapla"
Используя выходную переменную load
функция, которую вы храните переменную data
из вашего.mat-файла в структуру с именем data
- так оно становится вложенным. Просто используйте load
без какого-либо вывода, и это будет работать.
if exist('data.mat', 'file') == 2
%// data = load('data'); % does not work!
load('data'); % does work!
else
data = struct;
end
data(1).a = 42;
data(2).a = 3;
data(1).b = 41;
data(2).b = 4;
%// make sure you just store what you want to store, in this case "data"
save('data.mat','data')
Также я бы не стал объявлять data
глобальная переменная. Вместо этого вы можете использовать тот факт, что все функции вашего графического интерфейса пользователя являются частью одного и того же окна рисунка и поэтому имеют доступный дескриптор рисунка:
hFig = gcf;
Кроме того, разрешено добавлять динамические свойства, чтобы ваш экземпляр figure
так что просто храните ваши данные в самом дескрипторе рисунка:
hFig = gcf;
addprop(hFig,'globalData')
data = struct;
hFig.globalData = data;
% ...
и в следующей функции вы просто делаете:
data = hFig.globalData