将数据结构保存在现有的 .mat 文件中,无需嵌套
Save data structure in existing .mat-file without nesting
我创建了一个简单的 GUI,当我按下按钮 (SAVE) 时,系统会获取某些字段的值,计算某个函数并将结果保存在数据结构中。
我希望这个数据结构是程序外部的,也就是说它保留在 Matlab 的出口处,并且在下一次打开程序时这个数据结构必须是可用的和可升级的。
为此,我使用了一个全局 data
变量,我会在需要时保存和加载它。
问题是不能正常工作,data
结构填充奇怪
我给你看一张可能更能说明问题的 gif:
保存的结构是这样的:
如您所见,另一个中有一个结构,而不是元素列表。为什么?
我想要一个包含 n 个元素的 data
结构(其中 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);
谢谢!
通过使用 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
一个全局变量。相反,您可以使用这样一个事实,即您的 GUI 的所有功能都是同一图形的一部分 window,因此图形句柄可用:
hFig = gcf;
进一步允许添加 dynamic properties 做你的 figure
实例,所以只需将你的数据存储在图形句柄本身中:
hFig = gcf;
addprop(hFig,'globalData')
data = struct;
hFig.globalData = data;
% ...
在下一个函数中,您只需执行以下操作:
data = hFig.globalData
您遇到的问题是在加载 data.mat
文件时产生的。
此外,使用 data
作为 load
返回的变量名称会导致混淆。
说明
data = load('../data/data')
读取 data.mat
并将其包含的 "data" 存储在名为 data
的结构中,因此,您的结构实际上是结构 [=13= 的 filed
] 由 load
.
返回
您可以通过在 load
调用之后设置断点并检查变量 data
.
来测试它
您可以通过在加载 .mat
文件时从结构中提取 data
字段来解决此问题。
if(exist('data.mat', 'file') == 2)
% data = load('data');
tmp = load('data');
data=tmp.data
else
data = struct;
end
希望这对您有所帮助,
Qapla'
我创建了一个简单的 GUI,当我按下按钮 (SAVE) 时,系统会获取某些字段的值,计算某个函数并将结果保存在数据结构中。 我希望这个数据结构是程序外部的,也就是说它保留在 Matlab 的出口处,并且在下一次打开程序时这个数据结构必须是可用的和可升级的。
为此,我使用了一个全局 data
变量,我会在需要时保存和加载它。
问题是不能正常工作,data
结构填充奇怪
我给你看一张可能更能说明问题的 gif:
保存的结构是这样的:
如您所见,另一个中有一个结构,而不是元素列表。为什么?
我想要一个包含 n 个元素的 data
结构(其中 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);
谢谢!
通过使用 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
一个全局变量。相反,您可以使用这样一个事实,即您的 GUI 的所有功能都是同一图形的一部分 window,因此图形句柄可用:
hFig = gcf;
进一步允许添加 dynamic properties 做你的 figure
实例,所以只需将你的数据存储在图形句柄本身中:
hFig = gcf;
addprop(hFig,'globalData')
data = struct;
hFig.globalData = data;
% ...
在下一个函数中,您只需执行以下操作:
data = hFig.globalData
您遇到的问题是在加载 data.mat
文件时产生的。
此外,使用 data
作为 load
返回的变量名称会导致混淆。
说明
data = load('../data/data')
读取 data.mat
并将其包含的 "data" 存储在名为 data
的结构中,因此,您的结构实际上是结构 [=13= 的 filed
] 由 load
.
您可以通过在 load
调用之后设置断点并检查变量 data
.
您可以通过在加载 .mat
文件时从结构中提取 data
字段来解决此问题。
if(exist('data.mat', 'file') == 2)
% data = load('data');
tmp = load('data');
data=tmp.data
else
data = struct;
end
希望这对您有所帮助,
Qapla'