Сохранить структуру данных в существующем.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
Другие вопросы по тегам