利用纯m文件生成ui之简单版canny边缘提取
布局部分
%get the cannyedge of the pictures.
%调用说明:
%选择自己图片并且导入点击按钮即可(测试版)
% 版本号V1.0,编写于2019年12月12号 作者:neverland!
%%
h = figure('menubar','none',...
'NumberTitle','off',...
'Name','20177740--neverland的课程设计',... %窗口对象
'Position',[300 120 1000 800],...
'tag','figure1');
%坐标轴1
axes1 = axes('Units','pixels',...
'Parent',h,...
'position',[100 200 300 350],...
'XTick',[],...
'YTick',[],...
'Box','on',...
'tag','ax0');
%坐标轴2
axes2 = axes('Units','pixels',...
'Parent',h,...
'Position',[600 200 300 350],...
'XTick',[],...
'YTick',[],...
'Box','on',...
'tag','ax1');
%菜单作为控制按钮,选择原始图像
m1 = uimenu('parent',h,...
'Text','选择原始图像',...
'Position',1,...
'tag','menu1');
%canny边缘提取
m2 = uimenu('parent',h,...
'Text','Canny边缘提取',...
'Position',2,...
'tag','menu2');
在这里完成了基本的布局,其中生成了窗口,坐标轴以及2个菜单栏,主要是省事不用利用control去安排它的位置。
最为重要的部分
%%
handles = guihandles(h);
%%
handles.axes1 = axes1;
handles.axes2 = axes2;
set(m1,'callback',@m1_callback);
set(m2,'callback',@m2_callback);
guidata(h,handles);
由于生成的是ui界面,你需要一个句柄来存储,而且需要的是gui句柄,所以第一句话guihandles把窗口的对象都放入了handles这个句柄。生成句柄后,把两个坐标轴放入了handles的句柄中去。你可以把中个过程和另外blog里面说的容器一样。先得到了一个容器,注入一些水,需要的时候再抽出来。
set两句话是设置点击菜单栏按钮之后的反应,即两个callback,后面的@是函数的名称,之后在下文会写。
guidata(h,handles)是把h里面的内容都存入了handles中,具体请看下面参数传递部分。
参数传递
Matlab的gui参数传递主要有3种方式
-
global方式
利用global就比较简单,只要在每个function函数部分都global 变量就可完成传递,但是由于是全局变量,所以无法在这个文件中删除。 -
guidata方式
我做课设的时候用的是这种方式,比较常用的也是这种方式,每个函数前面先guidata(object)部分先读入句柄内已经有的部分,最后再guidata(object,handles)存贮起来。function [] = m1_callback(menu1,eventdata,~) handles = guidata(menu1); %获取句柄内的内容 [filename,pathname] = uigetfile({'*.jpg';'*.png';'*.tif';'*.*'},'Please select a pictures') truename = [pathname,filename]; p = imread(truename); axes(handles.axes1); imshow(p); handles.op = p; guidata(menu1,handles);
end
例如这里面,handles = guidata(menu1)
先读入了把handles里面的内容读取出来,那么menu1这里面就可以利用,进行完一番操作之后再把menu1做完操作后的东西存入handles里面即可。
3. setup-data & getappdata
这种方式我没有尝试过,但是我刚开始学习时别人就是利用这种方法的。
回调函数部分
前面的设置和参数传递完之后这个回调函数也相对非常重要
回调函数的编写方法是
function [输出] = 名称(object,evendata,handles)
倘若不需要则可以用~代替
这个object名称如果是利用guide生成可以不改,如果利用纯m生成则需要自己选取,否则会冲突,所以建议利用控件的tag属性来命名,这个eventdata是为了兼容将来版本的保留接口,这个ui里没咋用到。handles里我直接省略了。
function [] = m1_callback(menu1,eventdata,~)
handles = guidata(menu1); %获取句柄内的内容
[filename,pathname] = uigetfile({'*.jpg';'*.png';'*.tif';'*.*'},'Please select a pictures') %获取文件名和路径名
truename = [pathname,filename]; %拼接
p = imread(truename);
axes(handles.axes1); %控制显示的坐标轴
imshow(p);
handles.op = p; %存储内容进入handles句柄
guidata(menu1,handles); %更新handles里面内容
end
第一个函数部分首先读入了里面已经有了的句柄这部非常重要否则到时候无法控制坐标轴。
uigetfile是一种交互式选取文件的方法。
axes(handles.axes1)是用显示的坐标轴。
handles.op = p; 为handles又创建了一个op的内容,并且把p即图像赋值给了它。
guidata(menu1,handles)即又将menu1执行完的内容放入了handles里面。
点击上面的选择原始图像,并且选择图像即可。
function [] = m2_callback(menu2,eventdata,~)
handles = guidata(menu2);
op = handles.op;
chicun = size(op);
number = numel(chicun);
if number == 3
op = rgb2gray(op);
else
op = op;
end
cannyedge = edge(op,'canny');
axes(handles.axes2);
imshow(cannyedge);
end
第二个回调函数。handles = guidata(menu2)就不用再解释了
而op = handles.op; 因为之前已经存储过了op需要再找一个变量来存储它,当然你也可以直接调用handles.op因为第一句话已经读入了handles里面有的内容
chicun = size(op);
由于调用库函数的canny边缘提取,无法提取rgb的边缘,所以需要判断是否是3维图像。
cannyedge = edge(op,‘canny’);则是库函数的canny边缘提取
最后是坐标轴控制和显示图像。
完成后就是这样的ui界面了。
总的代码
%get the cannyedge of the pictures.
%调用说明:
%选择自己图片并且导入点击按钮即可(测试版)
% 版本号V1.0,编写于2019年12月12号 作者:neverland!
%%
h = figure('menubar','none',...
'NumberTitle','off',...
'Name','20177740--neverland的课程设计',... %窗口对象
'Position',[300 120 1000 800],...
'tag','figure1');
%坐标轴1
axes1 = axes('Units','pixels',...
'Parent',h,...
'position',[100 200 300 350],...
'XTick',[],...
'YTick',[],...
'Box','on',...
'tag','ax0');
%坐标轴2
axes2 = axes('Units','pixels',...
'Parent',h,...
'Position',[600 200 300 350],...
'XTick',[],...
'YTick',[],...
'Box','on',...
'tag','ax1');
%菜单作为控制按钮,选择原始图像
m1 = uimenu('parent',h,...
'Text','选择原始图像',...
'Position',1,...
'tag','menu1');
%canny边缘提取
m2 = uimenu('parent',h,...
'Text','Canny边缘提取',...
'Position',2,...
'tag','menu2');
%%
handles = guihandles(h);
%%
handles.axes1 = axes1;
handles.axes2 = axes2;
set(m1,'callback',@m1_callback);
set(m2,'callback',@m2_callback);
guidata(h,handles);
%%回调函数部分
function [] = m1_callback(menu1,eventdata,~)
handles = guidata(menu1); %获取句柄内的内容
[filename,pathname] = uigetfile({'*.jpg';'*.png';'*.tif';'*.*'},'Please select a pictures')
truename = [pathname,filename];
p = imread(truename);
axes(handles.axes1);
imshow(p);
handles.op = p;
guidata(menu1,handles);
end
function [] = m2_callback(menu2,eventdata,~)
handles = guidata(menu2);
op = handles.op;
chicun = size(op);
number = numel(chicun);
if number == 3
op = rgb2gray(op);
else
op = op;
end
cannyedge = edge(op,'canny');
axes(handles.axes2);
imshow(cannyedge);
end
这里面是总的代码,比较简单,少去了许多无用的注释,但是里面藏着许多的内容,对Matlab会有更深的了解。
最后,其实课设写了一个从原理上写canny边缘提取的ui,想要学习的话可以私信我,不过那份代码就需要有偿食用啦!
来源:CSDN
作者:N某人
链接:https://blog.csdn.net/weixin_43342986/article/details/103968485