Mudanças entre as edições de "Curso Matlab aplicado ao processamento de imagens - Aula 2"
(9 revisões intermediárias pelo mesmo usuário não estão sendo mostradas) | |||
Linha 1: | Linha 1: | ||
− | Nesta aula | + | Nesta aula vamos aprender a criar interfaces simples para scripts. |
− | + | __TOC__ | |
O Matlab possui uma ferramenta para simplificar a criação de GUIs, o [http://www.mathworks.com/help/matlab/gui-building-basics.html GUIDE]. Neste curso, vamos criar uma interface simples, com dois eixos de plot, um campo de entrada de dados, dois botões de radio e um botão de apertar. No primeiro eixo vamos plotar um seno, e no segundo vamos plotar um cosseno ou uma tangente, dependendo do botão de radio marcado. A frequência da senoide será inicialmente 0, mas poderá ser alterada através do campo de dado. | O Matlab possui uma ferramenta para simplificar a criação de GUIs, o [http://www.mathworks.com/help/matlab/gui-building-basics.html GUIDE]. Neste curso, vamos criar uma interface simples, com dois eixos de plot, um campo de entrada de dados, dois botões de radio e um botão de apertar. No primeiro eixo vamos plotar um seno, e no segundo vamos plotar um cosseno ou uma tangente, dependendo do botão de radio marcado. A frequência da senoide será inicialmente 0, mas poderá ser alterada através do campo de dado. | ||
Linha 9: | Linha 9: | ||
<br style="clear:both;"> | <br style="clear:both;"> | ||
− | + | ==Criação da interface== | |
Para iniciar a criação da interface, escolha a pasta que você quer que os arquivos estejam salvos e digite na janela de comandos: | Para iniciar a criação da interface, escolha a pasta que você quer que os arquivos estejam salvos e digite na janela de comandos: | ||
Linha 59: | Linha 59: | ||
Repare que nenhuma ação é executada ao clicar nos botões ou alterar o campo de texto. Isso acontece porque apenas a interface está criada, falta atribuir ações à cada uma das componentes. É isso que faremos na próxima etapa. | Repare que nenhuma ação é executada ao clicar nos botões ou alterar o campo de texto. Isso acontece porque apenas a interface está criada, falta atribuir ações à cada uma das componentes. É isso que faremos na próxima etapa. | ||
− | + | ==Atribuir uma ação às componentes== | |
Ao salvar a interface criada, dois arquivos são gerados pela ferramenta, um ''interface.fig'', que é a interface em si, e ''interface.m'' que é o código que indica a ação que cada componente gera. Este arquivo é organizado como funções, das quais as mais importantes são: | Ao salvar a interface criada, dois arquivos são gerados pela ferramenta, um ''interface.fig'', que é a interface em si, e ''interface.m'' que é o código que indica a ação que cada componente gera. Este arquivo é organizado como funções, das quais as mais importantes são: | ||
Linha 69: | Linha 69: | ||
Assim, para atribuir ações aos componentes, basta indicá-las no espaço correspondente à componente. Após escrever o código, não esqueça de salvar o arquivo. A seguir, vamos atribuir algumas ações às componentes: | Assim, para atribuir ações aos componentes, basta indicá-las no espaço correspondente à componente. Após escrever o código, não esqueça de salvar o arquivo. A seguir, vamos atribuir algumas ações às componentes: | ||
− | + | ===Ação do botão=== | |
Inclua na função '''pushbutton1_Callback''' o código: | Inclua na função '''pushbutton1_Callback''' o código: | ||
Linha 77: | Linha 77: | ||
salve, e execute a função. Repare que toda vez que o botão é pressionado, uma mensagem ''Botão pressionado'' é impressa na janela de comandos. | salve, e execute a função. Repare que toda vez que o botão é pressionado, uma mensagem ''Botão pressionado'' é impressa na janela de comandos. | ||
− | + | ===Plotando ao pressionar o botão=== | |
Para plotar um gráfico ao pressionar o botão, inclua na função '''pushbutton1_Callback''' o código: | Para plotar um gráfico ao pressionar o botão, inclua na função '''pushbutton1_Callback''' o código: | ||
Linha 87: | Linha 87: | ||
<br style="clear:both;"> | <br style="clear:both;"> | ||
− | + | ===Referenciando uma componente específica=== | |
Repare que o eixo em que o gráfico foi plotado não foi escolhido. Para escolher o eixo, é preciso passar para a função '''plot''' um indicador da componente a ser utilizada. Todas as componentes estão dispostas na variável ''handles'', struct criada automaticamente pela ferramenta '''GUIDE'''. Para esta interface, a variável ''handles'' possui os seguintes campos: | Repare que o eixo em que o gráfico foi plotado não foi escolhido. Para escolher o eixo, é preciso passar para a função '''plot''' um indicador da componente a ser utilizada. Todas as componentes estão dispostas na variável ''handles'', struct criada automaticamente pela ferramenta '''GUIDE'''. Para esta interface, a variável ''handles'' possui os seguintes campos: | ||
Linha 107: | Linha 107: | ||
Os valores atribuídos à cada campo não são muito importante, são as referências que o Matlab criou ao gerar a interface. Assim, para escolher o eixo em que o plot será feito, basta passar o valor '''handles.axes1''' ou '''handles.axes2'''. | Os valores atribuídos à cada campo não são muito importante, são as referências que o Matlab criou ao gerar a interface. Assim, para escolher o eixo em que o plot será feito, basta passar o valor '''handles.axes1''' ou '''handles.axes2'''. | ||
− | + | ===Guardando valores entre componentes=== | |
A ação de cada componente é atribuída por uma função dentro do arquivo ''interface.m''. Sendo funções, todas as variáveis criadas são apagadas após sua execução. Caso seja necessário guardar valores entre as ações das componentes, pode-se atribuir à variável ''handles'' outros campos, que guardarão os valores desejados. | A ação de cada componente é atribuída por uma função dentro do arquivo ''interface.m''. Sendo funções, todas as variáveis criadas são apagadas após sua execução. Caso seja necessário guardar valores entre as ações das componentes, pode-se atribuir à variável ''handles'' outros campos, que guardarão os valores desejados. | ||
Linha 161: | Linha 161: | ||
O botão foi pressionado 3 vezes | O botão foi pressionado 3 vezes | ||
− | + | ===Capturando o valor do campo de texto=== | |
O valor do campo de texto está armazenado na variável ''hObject'', que como o próprio nome já diz, é um objeto. Para atribuir ou receber valores da variável ''hObject'', usamos respectivamente as funções '''set(hObject,'<atributo>',<valor>)''' e '''get(hObject,'<atributo>')'''. Vimos anteriormente que a variável ''handles'' traz a referência para todos os componentes da interface. Em contrapartida, a variável ''hObject'' traz os atributos apenas da componente atual, que estamos atribuindo a ação. Cada componente tem seu conjunto de atributos. | O valor do campo de texto está armazenado na variável ''hObject'', que como o próprio nome já diz, é um objeto. Para atribuir ou receber valores da variável ''hObject'', usamos respectivamente as funções '''set(hObject,'<atributo>',<valor>)''' e '''get(hObject,'<atributo>')'''. Vimos anteriormente que a variável ''handles'' traz a referência para todos os componentes da interface. Em contrapartida, a variável ''hObject'' traz os atributos apenas da componente atual, que estamos atribuindo a ação. Cada componente tem seu conjunto de atributos. | ||
Linha 254: | Linha 254: | ||
Valor da variável f: ola amiguinhos | Valor da variável f: ola amiguinhos | ||
− | + | ===Utilizando os ''radiobuttons''=== | |
Cada ''radiobutton'' tem uma função de ação. O estado de um botão de ação é acessado pelo atributo '''Value''', que se for igual a 1 indica que o botão está marcado e se for igual a 0 indica que o botão não está marcado. Dependendo de vários fatores, ao marcar um botão, é possível que um botão previamente marcado seja desmarcado ou não. Assim, uma ação interessante de ser executada quando um ''radiobutton'' for marcado é a desmarcação dos outros ''radiobuttons''. Ou seja, na função de ação do ''radiobutton1'', '''radiobutton1_Callback''', escrevemos: | Cada ''radiobutton'' tem uma função de ação. O estado de um botão de ação é acessado pelo atributo '''Value''', que se for igual a 1 indica que o botão está marcado e se for igual a 0 indica que o botão não está marcado. Dependendo de vários fatores, ao marcar um botão, é possível que um botão previamente marcado seja desmarcado ou não. Assim, uma ação interessante de ser executada quando um ''radiobutton'' for marcado é a desmarcação dos outros ''radiobuttons''. Ou seja, na função de ação do ''radiobutton1'', '''radiobutton1_Callback''', escrevemos: | ||
Linha 336: | Linha 336: | ||
Radiobutton selecionado: 2 | Radiobutton selecionado: 2 | ||
− | + | ==Completando a interface== | |
Para completar a interface, seguimos os passos: | Para completar a interface, seguimos os passos: | ||
Linha 434: | Linha 434: | ||
− | ==Processamento de imagens== | + | <!--==Processamento de imagens== |
O processamento de imagens no Matlab é bastante facilitado. Nesta parte do curso, vamos estudar o básico do processamento de imagens, inicialmente para uma imagem em escala de cinza e depois para uma imagem colorida. | O processamento de imagens no Matlab é bastante facilitado. Nesta parte do curso, vamos estudar o básico do processamento de imagens, inicialmente para uma imagem em escala de cinza e depois para uma imagem colorida. | ||
Linha 440: | Linha 440: | ||
Inicialmente, salve as duas imagens abaixo no diretório de trabalho, e altere o diretório do Matlab para esta pasta. Para facilitar o trabalho, salve as variáveis como '''imagem1.jpeg''' e '''imagem2.jpeg'''. | Inicialmente, salve as duas imagens abaixo no diretório de trabalho, e altere o diretório do Matlab para esta pasta. Para facilitar o trabalho, salve as variáveis como '''imagem1.jpeg''' e '''imagem2.jpeg'''. | ||
− | :* [[Media:MATLAB_avancado_imagem1.jpeg|imagem1.jpeg]] | + | :* [[Media:MATLAB_avancado_imagem1.jpeg|imagem1.jpeg]] - Imagem de Daniel Teoli Jr, acessível em [http://commons.wikimedia.org/wiki/File:%27Untitled_Number_2%27_2012_Daniel_Teoli_Jr_LLR.jpg Link] |
− | :* [[Media:MATLAB_avancado_imagem2-2.jpeg|imagem2.jpeg]] | + | :* [[Media:MATLAB_avancado_imagem2-2.jpeg|imagem2.jpeg]] - Imagem de Joao Carlos Medau, acessível em [http://commons.wikimedia.org/wiki/File:Arara_Vermelha_(8496809574).jpg Link] |
===Imagem em escala de cinza=== | ===Imagem em escala de cinza=== | ||
Linha 544: | Linha 544: | ||
Marcas d'água são pequenos logos incluídos nas imagens, normalmente utilizados para informação de autoria. Vamos adicionar o logo do IFSC na imagem em escala de cinza ''x'' que estamos utilizando até agora. | Marcas d'água são pequenos logos incluídos nas imagens, normalmente utilizados para informação de autoria. Vamos adicionar o logo do IFSC na imagem em escala de cinza ''x'' que estamos utilizando até agora. | ||
− | Primeiro, baixamos o | + | Primeiro, baixamos o [[Media:MATLAB_avancado_logo_IFSC.gif|logo do IFSC]] e salvamos na mesma pasta que estamos trabalhando, com o nome '''logo.gif'''. Lemos o arquivo no Matlab com: |
>> marca = imread('logo.gif'); | >> marca = imread('logo.gif'); | ||
Linha 575: | Linha 575: | ||
<br style="clear:both;"> | <br style="clear:both;"> | ||
− | [[Imagem:MATLAB_avancado_basic_imagem_9-final.png|thumb|Imagem com marca d'água| | + | [[Imagem:MATLAB_avancado_basic_imagem_9-final.png|thumb|Imagem com marca d'água|700px|center]] |
+ | <br style="clear:both;"> | ||
+ | |||
+ | |||
+ | ====Suavização==== | ||
+ | |||
+ | Suavizar uma imagem significa reduzir sua nitidez. É realizado através do cálculo da média local ao redor de todos os pixels da imagem. No Matlab, isso é feito com a criação de uma matriz de média, chamada de ''máscara'' para realização de uma operação de ''convolução''. | ||
+ | |||
+ | - Primeiro, uma matriz de média é criada. Ela deve ser quadrada, de tamanho ímpar, e a soma de seus elementos deve resultar em 1: | ||
+ | |||
+ | >> mask1 = (1/9)*[1 1 1; 1 1 1; 1 1 1] | ||
+ | |||
+ | mask1 = | ||
+ | |||
+ | 0.1111 0.1111 0.1111 | ||
+ | 0.1111 0.1111 0.1111 | ||
+ | 0.1111 0.1111 0.1111 | ||
+ | |||
+ | >> sum(sum(mask1)) | ||
+ | |||
+ | ans = | ||
+ | |||
+ | 1 | ||
+ | |||
+ | - O cálculo da média é efetivado com o uso da função '''conv2'''. Essa função percorre a máscara por todos os ''pixels'' da imagem, realizando operações de multiplicação e soma. | ||
+ | |||
+ | >> suav1 = conv2(x,mask1); | ||
+ | |||
+ | - A imagem resultante tem porém, 1 ''pixel'' a mais em cada borda: | ||
+ | |||
+ | >> whos x suav1 | ||
+ | Name Size Bytes Class Attributes | ||
+ | |||
+ | suav1 601x509 2447272 double | ||
+ | x 599x507 303693 uint8 | ||
+ | |||
+ | - Assim, descartamos esses pixels: | ||
+ | |||
+ | >> suav1 = suav1(2:end-1, 2:end-1); | ||
+ | >> size(suav1) | ||
+ | |||
+ | ans = | ||
+ | |||
+ | 599 507 | ||
+ | |||
+ | - Para ver os resultados, exibimos as imagens lado a lado: | ||
+ | |||
+ | >> figure | ||
+ | >> subplot(1,2,1); imshow(x) | ||
+ | >> subplot(1,2,2); imshow(uint8(suav1)) | ||
+ | |||
+ | <br style="clear:both;"> | ||
+ | [[Imagem:MATLAB_avancado_basic_imagem_10.png|thumb|Imagem original e imagem suavizada|700px|center]] | ||
+ | <br style="clear:both;"> | ||
+ | |||
+ | |||
+ | Outros tipos de operadores de média podem ser utilizados, com máscaras maiores, ou mesmo não uniformes. Para máscaras uniformes, a função '''ones''' pode ser utilizada: | ||
+ | |||
+ | >> mask2 = (1/25)*ones(5,5) | ||
+ | |||
+ | mask2 = | ||
+ | |||
+ | 0.0400 0.0400 0.0400 0.0400 0.0400 | ||
+ | 0.0400 0.0400 0.0400 0.0400 0.0400 | ||
+ | 0.0400 0.0400 0.0400 0.0400 0.0400 | ||
+ | 0.0400 0.0400 0.0400 0.0400 0.0400 | ||
+ | 0.0400 0.0400 0.0400 0.0400 0.0400 | ||
+ | |||
+ | >> mask3 = (1/15)*[1 2 1; 2 3 2; 1 2 1] | ||
+ | |||
+ | mask3 = | ||
+ | |||
+ | 0.0667 0.1333 0.0667 | ||
+ | 0.1333 0.2000 0.1333 | ||
+ | 0.0667 0.1333 0.0667 | ||
+ | |||
+ | |||
+ | ====Detecção de bordas==== | ||
+ | |||
+ | A detecção de bordas em imagens é feita de forma semelhante à suavização, porém uma máscara diferente é utilizada. Neste curso vamos usar uma máscara específica, de [http://pt.wikipedia.org/wiki/Filtro_Sobel Sobel], mas existem muitas outras que podem ser utilizadas, com vantagens e desvantagens específicas. A máscara de Sobel é definida para bordas verticais e horizontais, respectivamente: | ||
+ | |||
+ | >> sobel_v = [-1, -2, -1; 0, 0, 0; 1, 2, 1] | ||
+ | |||
+ | sobel_v = | ||
+ | |||
+ | -1 -2 -1 | ||
+ | 0 0 0 | ||
+ | 1 2 1 | ||
+ | |||
+ | >> sobel_h = [-1, 0, 1; -2, 0, 2; -1, 0, 1] | ||
+ | |||
+ | sobel_h = | ||
+ | |||
+ | -1 0 1 | ||
+ | -2 0 2 | ||
+ | -1 0 1 | ||
+ | |||
+ | Ao aplicar os operadores na imagem, usando a função '''conv2''', temos como resultado as imagens abaixo: | ||
+ | |||
+ | >> borda_v = conv2(x,sobel_v); | ||
+ | >> borda_h = conv2(x,sobel_h); | ||
+ | >> borda_v = borda_v(2:end-1,2:end-1); | ||
+ | >> borda_h = borda_h(2:end-1,2:end-1); | ||
+ | |||
+ | >> figure | ||
+ | >> subplot(1,2,1); imshow(uint8(borda_v)); title('Bordas verticais da imagem') | ||
+ | >> subplot(1,2,2); imshow(uint8(borda_h)); title('Bordas horizontais da imagem') | ||
+ | |||
+ | <br style="clear:both;"> | ||
+ | [[Imagem:MATLAB_avancado_basic_imagem_11-1.png|thumb|Bordas verticais e horizontais da imagem|700px|center]] | ||
+ | <br style="clear:both;"> | ||
+ | |||
+ | Pode também ser feita a soma das componentes verticais e horizontais das bordas: | ||
+ | |||
+ | >> borda = borda_v + borda_h; | ||
+ | >> figure | ||
+ | >> subplot(1,2,1); imshow(x); title('Imagem original') | ||
+ | >> subplot(1,2,2); imshow(uint8(borda)); title('Bordas da imagem') | ||
+ | |||
+ | <br style="clear:both;"> | ||
+ | [[Imagem:MATLAB_avancado_basic_imagem_11-2.png|thumb|Imagem original e imagem das bordas|700px|center]] | ||
<br style="clear:both;"> | <br style="clear:both;"> | ||
Linha 652: | Linha 772: | ||
[[Imagem:MATLAB_avancado_basic_imagem_6.png|thumb|Paleta de cores|400px|center]] | [[Imagem:MATLAB_avancado_basic_imagem_6.png|thumb|Paleta de cores|400px|center]] | ||
<br style="clear:both;"> | <br style="clear:both;"> | ||
+ | |||
+ | --> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | [[Curso Matlab aplicado ao processamento de imagens|Voltar para a página inicial do curso]] |
Edição atual tal como às 10h32min de 9 de dezembro de 2014
Nesta aula vamos aprender a criar interfaces simples para scripts.
O Matlab possui uma ferramenta para simplificar a criação de GUIs, o GUIDE. Neste curso, vamos criar uma interface simples, com dois eixos de plot, um campo de entrada de dados, dois botões de radio e um botão de apertar. No primeiro eixo vamos plotar um seno, e no segundo vamos plotar um cosseno ou uma tangente, dependendo do botão de radio marcado. A frequência da senoide será inicialmente 0, mas poderá ser alterada através do campo de dado.
Criação da interface
Para iniciar a criação da interface, escolha a pasta que você quer que os arquivos estejam salvos e digite na janela de comandos:
>> guide
Na janela quick start que apareceu, escolha Blank GUI e pressione OK.
A janela que se abre é o editor de interfaces. É aí que os botões são dispostos na janela. Para adicionar uma componente, basta clicar no botão na parte esquerda e arrastá-lo para a parte central, na posição desejada. Cada componenteadicionada possui atributos, que podem ser visualizados através de um duplo clique:
Inicie com a criação de 3 painéis, como dispostos na figura:
Inclua 2 axes nos painéis superior esquerdo e direito:
Por fim, inclua um campo edit text no painel inferior esquerdo dois radiobuttons na parte inferior do painel direito:
É possível alterar as informações escritas na interface, clicando duas vezes na componente e alterando o campo Title, no caso dos painéis, ou String para os demais. A interface concluída pode ser vista abaixo:
Salve o arquivo com o nome interface, uma janela com vários códigos irá aparecer. Ao digitar na janela de comando o comando interface, a janela da interface se abrirá.
Repare que nenhuma ação é executada ao clicar nos botões ou alterar o campo de texto. Isso acontece porque apenas a interface está criada, falta atribuir ações à cada uma das componentes. É isso que faremos na próxima etapa.
Atribuir uma ação às componentes
Ao salvar a interface criada, dois arquivos são gerados pela ferramenta, um interface.fig, que é a interface em si, e interface.m que é o código que indica a ação que cada componente gera. Este arquivo é organizado como funções, das quais as mais importantes são:
- interface: Abre a interface criada.
- interface_OpeningFcn: Última função executada antes que a interface seja efetivamente criada. É usada para inicialização de variáveis, etc.
- <componente>_Callback: Ação executada pelo componente ao ser pressionado.
Assim, para atribuir ações aos componentes, basta indicá-las no espaço correspondente à componente. Após escrever o código, não esqueça de salvar o arquivo. A seguir, vamos atribuir algumas ações às componentes:
Ação do botão
Inclua na função pushbutton1_Callback o código:
display('Botão pressionado')
salve, e execute a função. Repare que toda vez que o botão é pressionado, uma mensagem Botão pressionado é impressa na janela de comandos.
Plotando ao pressionar o botão
Para plotar um gráfico ao pressionar o botão, inclua na função pushbutton1_Callback o código:
plot(randn(1,10))
Referenciando uma componente específica
Repare que o eixo em que o gráfico foi plotado não foi escolhido. Para escolher o eixo, é preciso passar para a função plot um indicador da componente a ser utilizada. Todas as componentes estão dispostas na variável handles, struct criada automaticamente pela ferramenta GUIDE. Para esta interface, a variável handles possui os seguintes campos:
handles = figure1: 191.0381 uipanel3: 27.0389 uipanel2: 25.0389 uipanel1: 19.0397 pushbutton1: 192.0381 radiobutton1: 34.0389 radiobutton2: 33.0389 axes2: 28.0389 edit1: 26.0389 axes1: 20.0389 output: 191.0381
Os valores atribuídos à cada campo não são muito importante, são as referências que o Matlab criou ao gerar a interface. Assim, para escolher o eixo em que o plot será feito, basta passar o valor handles.axes1 ou handles.axes2.
Guardando valores entre componentes
A ação de cada componente é atribuída por uma função dentro do arquivo interface.m. Sendo funções, todas as variáveis criadas são apagadas após sua execução. Caso seja necessário guardar valores entre as ações das componentes, pode-se atribuir à variável handles outros campos, que guardarão os valores desejados.
Por exemplo, para criar um contador de apertos no botão, precisamos de uma variável que guarde o número de vezes que o botão foi pressionado. Criamos um campo chamado contador na variável handles, inicializado com 0, e atribuímos a ação de somar 1 sempre que o botão for pressionado.
Para criar o campo e inicializá-lo com zero, inserimos um código à função interface_OpeningFcn, que ficará assim:
% --- Executes just before interface is made visible. function interface_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to interface (see VARARGIN) handles.contador = 0; %------------------------- Criando o contador % Choose default command line output for interface handles.output = hObject; % Update handles structure guidata(hObject, handles);
O incremento do contador, e a impressão da mensagem com o número de vezes que o botão foi pressionado são incluídos na função pushbutton1_Callback:
handles.contador = handles.contador + 1; display(['O botão foi pressionado ' num2str(handles.contador) ' vezes'])
Porém, ao executar a interface e pressionar o botão, observamos que aparece sempre a mesma mensagem:
>> interface O botão foi pressionado 1 vezes O botão foi pressionado 1 vezes O botão foi pressionado 1 vezes
Isso acontece porque as funções de ação não retornam nenhum valor, ou seja, a alteração realizada na variável handle.contador se perde após a execução da função. Para salvar as variáveis, é necessário usar a função guidata(hObject, handles);. Assim, a função pushbutton1_Callback ficará:
function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) handles.contador = handles.contador + 1; display(['O botão foi pressionado ' num2str(handles.contador) ' vezes']) guidata(hObject, handles);
Com isso, o problema está resolvido:
>> interface O botão foi pressionado 1 vezes O botão foi pressionado 2 vezes O botão foi pressionado 3 vezes
Capturando o valor do campo de texto
O valor do campo de texto está armazenado na variável hObject, que como o próprio nome já diz, é um objeto. Para atribuir ou receber valores da variável hObject, usamos respectivamente as funções set(hObject,'<atributo>',<valor>) e get(hObject,'<atributo>'). Vimos anteriormente que a variável handles traz a referência para todos os componentes da interface. Em contrapartida, a variável hObject traz os atributos apenas da componente atual, que estamos atribuindo a ação. Cada componente tem seu conjunto de atributos.
Para ver os atributos disponíveis no campo de texto, incluímos na sua função de ação (edit1_Callback) o código get(hObject). Ao alterar o valor do campo, a seguinte mensagem é impressa na janela de comandos:
BackgroundColor = [1 1 1] Callback = [ (1 by 1) function_handle array] CData = [] Enable = on Extent = [0 0 24.8 1.38462] FontAngle = normal FontName = MS Sans Serif FontSize = [8] FontUnits = points FontWeight = normal ForegroundColor = [0 0 0] HorizontalAlignment = center KeyPressFcn = ListboxTop = [1] Max = [1] Min = [0] Position = [3.6 1.76923 32.2 2.30769] String = Valor alterado------------- Style = edit SliderStep = [0.01 0.1] TooltipString = Units = characters Value = [0] BeingDeleted = off ButtonDownFcn = Children = [] Clipping = on CreateFcn = [ (1 by 1) function_handle array] DeleteFcn = BusyAction = queue HandleVisibility = on HitTest = on Interruptible = on Parent = [25.0402] Selected = off SelectionHighlight = on Tag = edit1 Type = uicontrol UIContextMenu = [] UserData = [] Visible = on
Repare que o atributo String recebeu o valor digitado no campo de texto. Assim, é esse o campo que precisamos ler se quisermos receber o valor da frequência digitado pelo usuário. Para guardar o valor digitado, criamos um campo na variável handles.
Criamos o campo f na variável handles e inicializamos com zero, na função interface_OpeningFcn:
function interface_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to interface (see VARARGIN) handles.f = 0; % Choose default command line output for interface handles.output = hObject; % Update handles structure guidata(hObject, handles);
Adicionamos a ação de guardar o valor digitado no campo de texto, na função edit1_Callback. Não esquecer de salvar a alteração na variável com a função guidata(hObject, handles);:
function edit1_Callback(hObject, eventdata, handles) % hObject handle to edit1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) handles.f = get(hObject,'String'); guidata(hObject, handles);
Por fim, configuramos no botão a ação de mostrar na janela de comandos o valor da variável handles.f:
function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) display(['Valor da variável f: ' handles.f])
Veja as mensagens exibidas, sempre que o botão é pressionado
>> interface Valor da variável f: 4 Valor da variável f: 5 Valor da variável f: ola amiguinhos
Utilizando os radiobuttons
Cada radiobutton tem uma função de ação. O estado de um botão de ação é acessado pelo atributo Value, que se for igual a 1 indica que o botão está marcado e se for igual a 0 indica que o botão não está marcado. Dependendo de vários fatores, ao marcar um botão, é possível que um botão previamente marcado seja desmarcado ou não. Assim, uma ação interessante de ser executada quando um radiobutton for marcado é a desmarcação dos outros radiobuttons. Ou seja, na função de ação do radiobutton1, radiobutton1_Callback, escrevemos:
set(handles.radiobutton1,'Value',1) set(handles.radiobutton2,'Value',0)
E na função de ação do radiobutton2, radiobutton2_Callback, escrevemos:
set(handles.radiobutton1,'Value',0) set(handles.radiobutton2,'Value',1)
Repare que os atributos dos componentes também podem ser acessados a partir da referência disponível na variável handles.
É interessante também guardar o radiobutton escolhido. Para isso, criamos uma variável chamada estado, como um campo da variável handles. Esta variável terá os valores 1 ou 2, dependendo do radiobutton escolhido. Além disso, pode ser necessário inserir um estado inicial dos radiobuttons, evitando que todos fiquem desmarcados. Assim, para trabalhar com os radiobuttons fazemos:
- Adicionamos na função interface_OpeningFcn a criação da variável estado e a rotina de inserção do seu estado inicial:
function interface_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to interface (see VARARGIN) % Diz que o botão selecionado é o 1 handles.estado = 1; % Inicializa o estado dos botões set(handles.radiobutton1,'Value',1) set(handles.radiobutton2,'Value',0) % Choose default command line output for interface handles.output = hObject; % Update handles structure guidata(hObject, handles);
- Dizemos que, ao selecionar um radiobutton o outro deve ser desmarcado, e guardamos o estado dos botões:
function radiobutton1_Callback(hObject, eventdata, handles) % hObject handle to radiobutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Diz que o botão selecionado é o 1 handles.estado = 1; set(handles.radiobutton1,'Value',1) set(handles.radiobutton2,'Value',0) % Update handles structure guidata(hObject, handles);
function radiobutton2_Callback(hObject, eventdata, handles) % hObject handle to radiobutton2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Diz que o botão selecionado é o 2 handles.estado = 2; set(handles.radiobutton1,'Value',0) set(handles.radiobutton2,'Value',1) % Update handles structure guidata(hObject, handles);
- Inserimos uma função de display como ação do botão:
function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) display(['Radiobutton selecionado: ' num2str(handles.estado)])
Repare que foi necessário converter o número para string. Ao executar a interface, observamos o resultado esperado:
>> interface Radiobutton selecionado: 1 Radiobutton selecionado: 2 Radiobutton selecionado: 2
Completando a interface
Para completar a interface, seguimos os passos:
- Na função interface_OpeningFcn, inserimos um estado inicial para os botões, geramos um estado inicial para a frequência dos sinais, geramos o eixo do tempo no qual os sinais estarão definidos e fazemos os plots com os valores padrão:
function interface_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to interface (see VARARGIN) % ------------------------------------------------------ % Diz que o botão selecionado é o 1 handles.estado = 1; % Inicializa o estado dos botões set(handles.radiobutton1,'Value',1) set(handles.radiobutton2,'Value',0) % Inicializa os valores dos sinais handles.f = 0; handles.t = 0:0.001:1; % Faz os plots com os valores padrão plot(handles.axes1,sin(2*pi*handles.f*handles.t)) plot(handles.axes2,cos(2*pi*handles.f*handles.t)) % ------------------------------------------------------ % Choose default command line output for interface handles.output = hObject; % Update handles structure guidata(hObject, handles);
- Na função radiobutton1_Callback, incluímos os códigos para o comportamento adequado:
function radiobutton1_Callback(hObject, eventdata, handles) % hObject handle to radiobutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Diz que o botão selecionado é o 1 handles.estado = 1; set(handles.radiobutton1,'Value',1) set(handles.radiobutton2,'Value',0) % Update handles structure guidata(hObject, handles);
- O mesmo para a função radiobutton2_Callback
function radiobutton2_Callback(hObject, eventdata, handles) % hObject handle to radiobutton2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Diz que o botão selecionado é o 1 handles.estado = 2; set(handles.radiobutton1,'Value',0) set(handles.radiobutton2,'Value',1) % Update handles structure guidata(hObject, handles);
- Na função edit1_Callback, armazenamos o valor digitado no campo de texto na variável f
function edit1_Callback(hObject, eventdata, handles) % hObject handle to edit1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Pega o valor digitado handles.f = str2double(get(hObject,'String')); % Update handles structure guidata(hObject, handles);
- Por fim, na função pushbutton1_Callback, plotamos o seno com o valor atual de frequência e selecionamos o segundo plot baseados no radiobutton escolhido:
function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Faz os plots com os valores padrão plot(handles.axes1,sin(2*pi*handles.f*handles.t)) if handles.estado == 1 plot(handles.axes2,cos(2*pi*handles.f*handles.t)) elseif handles.estado == 2 plot(handles.axes2,tan(2*pi*handles.f*handles.t)) end
A interface completa está disponível abaixo: