一、matlab开发GUI

下面介绍使用matlab开发可独立安装运行的exe小程序的方法。

1.GUI和app

以前MATLAB中独立程序的开发模块叫做GUI,新版本中用app代替,且逐步淘汰GUI模块,但两者大同小异,官方也提供了两者转换的工具。下面主要以app模块为主来展开。

2.app的创建

(1)app的创建如下图所示,可以建立空白app,也可以使用模板。
在这里插入图片描述
(2)新建app后,可以在设计器左边的空间栏将个字UI控件拖拽到UI中,然后在右侧的控件检查器中调整修改控件样式和默认的值。
在这里插入图片描述
(3)选择控件的回调设置,可以让某个控件的回调和其他控件绑定,也可以单独添加某些控件的回调,比如点某个按钮控件相关内容会显示在文本控件中。设置完回调后,会自动跳到代码视图的相关代码段,进行进一步编程。
在这里插入图片描述
在这里插入图片描述
(4)matlab中有几个常用的app控件:
① 按钮控件;
②TextArea控件,可以用来显示数据,设置其app.TextArea.Value值来改变显示,根据内容长度自动添加滑动条;
③EditField控件,获取用户输入的输入框,通过其app.EditField.Value值来获取用户输入值;
④Label控件,作为UI上的说明文字单独存在,无需用户互动;
⑤Figure控件,图片显示框,通过设置app.Image.ImageSource=‘图片路径’来显示图片;
⑥UIAxis控件,画图显示框,通过在画图语句中添加app.UIAxis语句来实现指定UI位置出图;
⑦UITable控件,用来显示矩阵数据,注意如果是一个cell数组,其元包类型只能为数字、字符(string),所以使用时一般加上 app.UITable.Data = string(view);
⑧目前还未摸索出在UI固定位置imshow图片的方法,有待研究。

3.参数传递

(1)同一UI的不同控件
之前的GUI模块中可以用全局变量来传递数据,在app中大部分控件的值都存储在自身的类中,因此可以直接通过类似app.控件.Value来跨控件调用变量值。比如下面的例子:

 % Button pushed function: Button_4
function Button_4Pushed(app, event)
    xlswrite(app.TextArea_2.Value{1},app.UITable_2.Data,"个人打卡统计");
end

(2)不同UI之间传参
参考博文: https://blog.csdn.net/hahahahhahha/article/details/115872871
可以使用公有函数,比如在界面f1中设置公有函数,然后在界面f2中调用
在这里插入图片描述
在这里插入图片描述
(3)函数传参
直接新建函数

function [output] = fun(input) %% fun就是函数名,也必须为函数程序文件保存的文件名
output = input;
end

如果函数输入参数涉及到UI中多个控件的值,可以将这些值全部装进一个cell数组进行传递,比如如下例子:

input = {app.TextArea.Value,app.TextArea_2.Value,app.DatePicker.Value,app.DatePicker_2.Value,app.EditField_3.Value,...
                     app.EditField_2.Value,app.EditField_4.Value,app.EditField_14.Value,app.EditField_15.Value,...
                     app.EditField_10.Value,app.EditField_11.Value,app.EditField_12.Value,app.EditField_13.Value,app.EditField_16.Value,...
                     app.EditField_17.Value,app.EditField_18.Value};
output = kaoqin(input);

4.程序封装

app可以直接打包成新的app安装程序,也可以像以前的GUI以前打包成独立安装的exe文件,在命令窗口输入deploytool调出部署菜单,如下所示:
在这里插入图片描述
(1)首先选择主程序,系统自动添加所有相关文件;
(2)再选择matlab插件的安装方式,需要部署在没有安装matlab的电脑上可以选择在安装时自动联网下载matlab runtime插件,该插件越800M;
(3)然后填写必要信息,选择splash图片;
(4)最后点击打包,打包后会生成3个文件夹,如下图所示:
在这里插入图片描述
其中第一个是完全独立安装的exe程序

5.程序安装

没有matlab的电脑确保联网安装即可。
在这里插入图片描述

二、matlab编程纪要

1.数据类型纪要

(1)string,char和cell

a = "abcd"; % 字符string类型
a = ["abcd","bcde"]; %字符数组
a(2) %其结果为bcde

b = 'abcd'; % 字符串char类型
b(2) %其结果为b

c = {"abcd",'bcde'}; %cell数组,其第一个元素为string,第二个元素为char
c{2}(2) %其结果为c

(2)判断变量类型

a = {1}; % a是一个cell
isa(a,'cell') % 其结果为1
isa(a{1},'double') % 其结果为1,元胞数组a的第一个元素是double类型

类型关键词有:
在这里插入图片描述

2.hdf文件读取

(1)使用hdfinfo函数显示hdf文件中有哪些变量;
(2)再用hdfread或hdf5read读取特定变量。

%% 适用hdf4及以下版本
hdfinfo('A.hdf'); %通过显示hdf文件信息,确认要读取哪些变量
lon = hdfread('A.hdf','LON'); %其中LON是A.hdf中原有的变量

%% 适用hdf5版本
hdf5info('A.hdf'); %通过显示hdf文件信息,确认要读取哪些变量
lon = hdf5read('A.hdf','LON'); %其中LON是A.hdf中原有的变量

3.shp文件读取

(1)使用shapeinfo函数显示shp矢量文件中有哪些变量;

shapeinfo('巡查记录.shp')
% 显示的信息如下
%包含以下字段的 struct:
%
%       Filename: [3×41 char]
%     ShapeType: 'Point'
%    BoundingBox: [2×2 double]
%    NumFeatures: 15
%     Attributes: [5×1 struct]

(2)可直接使用shaperead读取整个适量文件;
(3)再引用(2)中的具体成员变量来取值。

shp = shaperead(input);
output(2:col+1,1) = {shp.Id}; % 获取点的序号
output(2:col+1,2) = {shp.name}; % 获取巡查人字段
output(2:col+1,3) = {shp.X}; % 获取点的横坐标,矢量文件中是自带位置信息的,注意应于字段名称区分开
output(2:col+1,4) = {shp.Y}; % 获取点的纵坐标
output(2:col+1,5) = {shp.date}; % 获取巡查时间

4.netcdf文件读取

(1)使用ncinfo函数显示netcdf文件中有哪些变量;
(2)再用ncread读取特定变量;
(3)nc文件通常需要提取自己需要的研究范围,这时候就要把nc文件中的lat和lon也读出来,对照自己的研究区域经纬度对应在lat和lon中的范围确定行列的上下限序号;
(4)使用contourf画图检查空间范围截取的是否正确:

finfo = ncinfo('example.nc');
disp(finfo);
lon  = ncread('example.nc','lon');
lat = ncread('example.nc','lat');
peaksData  = ncread('example.nc','peaks');
contourf(lat,lon,peaksData);

5.常用统计函数

(1)百分位数

prctile(X,p) % X为数据列或行,p为多少百分位[0,100]之间

(2)方差

var(A) % A为数据列或行

(3)标准差

std(A) % A为数据列或行

(4)相关性系数

[rho,pval] = corr(X,Y) % X和Y为维度一致的数据行或列,rho为相关系数,pval为置信度
corr2(A,B) % A和B为两个维度一致的矩阵

6.画图

(1)contourf

contourf(lat,lon,data); % X轴数据lat(一维),Y轴数据lon(一维),Z值数据data(矩阵)
colorbar;
%% 可设置数字标签、颜色条

在这里插入图片描述

(2)surf

[LAT, LON] = meshgrid(lat,lon);% 用一维向量lat和lon创建同型矩阵LAT和LON
surf(LAT,LON,data); % X轴数据LAT(矩阵),Y轴数据LON(矩阵),Z值数据data(矩阵)
%% 三维曲面图。 

在这里插入图片描述

(3)plot

x = linspace(-2*pi,2*pi);
y1 = sin(x);
y2 = cos(x);
figure
plot(x,y1,x,y2) % 画两条曲线,可指定颜色、样式、数据标签
plot(x,y1,'g',x,y2,'b--o',x,y3,'c*') % x-y1绿色无点,x-y2蓝色圆圈,x-y3棕色星号

在这里插入图片描述

(4)imshow

corn_gray = imread('corn.tif',3);
imshow(corn_gray) %显示读取的图像或者直接显示路径中的图像文件
imshow('peppers.png')

在这里插入图片描述

(5)subplot

%% 在同一个图框中画多幅图
%% 2幅图上下排成1列,即2行×1列,最后一个参数为子图的顺序
subplot(2,1,1);
x = linspace(0,10);
y1 = sin(x);
plot(x,y1)
subplot(2,1,2); 
y2 = sin(5*x);
plot(x,y2)

在这里插入图片描述

subplot(2,2,1); % 2行×2列图的第一个
x = linspace(-3.8,3.8);
y_cos = cos(x);
plot(x,y_cos);
title('Subplot 1: Cosine')

subplot(2,2,2); % 2行×2列图的第二个
y_poly = 1 - x.^2./2 + x.^4./24;
plot(x,y_poly,'g');
title('Subplot 2: Polynomial')

subplot(2,2,[3,4]); %% 第3和4张图组合
plot(x,y_cos,'b',x,y_poly,'g');
title('Subplot 3 and 4: Both')

在这里插入图片描述

(6)图形叠加

figure('Name','Measured Data'); % 创建图框并显示名称
% 画第一个图
hold on;
% 画第二个图
hold off;

7.空间插值

(1)interp线性内插加密数据

x = [1:1:9]
interp(x,2)

在这里插入图片描述
(2)interp2 网格插值

Vq = interp2(X,Y,V,Xq,Yq); % 已知X、Y、V,求Xq、Yq对应的Vq值
x = [1:1:9]
y = x.^2
v = x'*y
xq=2
yq=4
interp2(x,y,v,xq,yq) % 结果为8

插值方法关键字如下,其中对于自然界的观测数据常用nearest和spline方法:
在这里插入图片描述
(3)fit工具箱
命令输入 cftool调出拟合工具箱
在这里插入图片描述

8.其他记录

(1)矩阵排序

A = [3 6 5; 7 -2 4; 1 0 -9];
B = sort(A,2); %‘2’表示对A的每一行元素排序
%B = 3×3
%     3     5     6
%    -2     4     7
%    -9     0     1

C = sortrows(A,1) %对A中第1列进行扩展排序
% C =
%     1     0    -9
%     3     6     5
%     7    -2     4

(2)变量自身元素的统计

a = [1,2,3,0]
sum(a~=0) % 统计a中不为0的元素个数,结果为3
find(~a) % 返回a中不为0的元素索引,结果为4
b = "abcd" % b可以是字符或字符串类型
strfind(b,'c') % 返回字符b中'c'的索引,其结果为3

(3)选择文件窗口

[wfile,wpath] = uigetfile('MultiSelect',"on",'*.xlsx','选择外勤记录表'); % 多选
% wfile为文件名,选择多个文件是为cell,选择一个为char
%wpath为文件夹路径,char类型

(4)遍历文件夹批量处理

inpath1 = 'D:\land\20201112\pic\jpg';
dat = dir(inpath1); % 获取根目录下的内容名称
for i = 1:length(dat)
   fprintf(strcat('***************** 正在处理 ', num2str(i),'/',num2str(length(dat)),'\n')); % 打印处理进度
   if(~isequal(dat(i).name,'.') && ~isequal(dat(i).name,'..')) % 剔除系统自动生成的隐藏目录
       if(dat(i).isdir) % 若不是子目录,则继续处理
           subdir = fullfile(inpath1,dat(i).name); % 生成子目录的绝对路径
           subdat = dir(subdir); % 获取子目录下的数据名称
           for j=1:length(subdat)
               if(~isequal(subdat(j).name,'.') && ~isequal(subdat(j).name,'..')) % 剔除系统自动生成的隐藏目录
                   datinpath1 = fullfile(subdir,subdat(j).name);
                   data1=imread(datinpath1);
               end
           end
       end
   end
end

(5)catch异常

try % 若可以正常读数据,则进行后续处理
	data1=imread(datinpath1);
catch % 若读取数据失败,则打印错误数据信息
    fprintf(strcat('警告!读取数据失败: ' , dat(i).name ,'\n'));
end

(6)表格读写

%% 将表格内容以元胞数组形式读入内存
% 设置导入选项并导入数据
opts = spreadsheetImportOptions("NumVariables", 9); % 读9列
% 指定工作表和范围
opts.Sheet = 1; % 指定读取表单
opts.DataRange = "A:I"; % 指定读取行列范围
% 指定列名称和类型
opts.VariableNames = ["VarName1", "VarName2", "VarName3", "VarName4", "VarName5", "VarName6", "VarName7", "VarName8", "VarName9"];
opts.VariableTypes = ["string", "string", "string", "string", "string", "string", "string", "string", "string"];
% 指定变量属性
opts = setvaropts(opts, ["VarName1", "VarName2", "VarName3", "VarName4", "VarName5", "VarName6", "VarName7", "VarName8", "VarName9"], "WhitespaceRule", "preserve");
opts = setvaropts(opts, ["VarName1", "VarName2", "VarName3", "VarName4", "VarName5", "VarName6", "VarName7", "VarName8", "VarName9"], "EmptyFieldRule", "auto");
% 导入数据
data = readtable(inputArg1, opts, "UseExcel", false);
% 转换为输出类型
data = table2cell(data);
numIdx = cellfun(@(x) ~isnan(str2double(x)), data);
data(numIdx) = cellfun(@(x) {str2double(x)}, data(numIdx));
% 清除临时变量
clear opts

(7)保存变量

p = rand(1,10);
q = ones(10);
save('pqfile.mat','p','q')
save('pqfile.txt','p','q','-ascii')

(8)创建目录

f (exist(datapath) == 0) % 若没有该数据名称的文件夹,则创建目录并写入数据
           mkdir(datapath);
           imwrite(data1,strcat(datapath, '\' ,dataname,'.jpg'));
       else % 若有该数据名称的文件夹,则打印错误信息
           fprintf('警告!数据文件目录重复!',dataname);
           fprintf('\n');
       end 

(9)图片读取与保存

path = "D:\land\merge_file_same_name\p2\";
path1 = "D:\land\merge_file_same_name\2018图斑";
path2 = "D:\land\merge_file_same_name\林业图版汇总";
path3 = "D:\land\merge_file_same_name\前期影像位置";
dat = dir(path1);
%% 根目录数据处理
for i = 3:length(dat)
   fprintf("***************** 正在处理 "+ num2str(i-2)+"/"+num2str(length(dat)-2));
   fprintf('\n');
   datpath1 = fullfile(path1,dat(i).name);
   datpath2 = fullfile(path2,dat(i).name);
   datpath3 = fullfile(path3,dat(i).name);
   try
      p1=imread(datpath1);
      p2=imread(datpath2);
      p3=imread(datpath3);
   catch
       fprintf("eror: " + dat(i).name);
       fprintf('\n');
       i=i+1;
   end
   mkdir(path+dat(i).name(1:end-4));
   imwrite(p1,path+dat(i).name(1:end-4)+'\'+dat(i).name(1:end-4)+'(1).jpg');
   mwrite(p2,path+dat(i).name(1:end-4)+'\'+dat(i).name(1:end-4)+'(2).jpg');
   imwrite(p3,path+dat(i).name(1:end-4)+'\'+dat(i).name(1:end-4)+'(3).jpg');
end

更多推荐