MATLAB newbie - Display Photos above panel in guide - matlab

i want to display photo above the panel , i see the documentation here : http://www.mathworks.com/help/matlab/ref/uistack.html
but it only mention how to use this function (uistack) only in figure
my program till now :
my code :
function varargout = panel(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', #panel_OpeningFcn, ...
'gui_OutputFcn', #panel_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
handles.output = hObject;
guidata(hObject, handles);
function varargout = panel_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
function pushbutton1_Callback(hObject, eventdata, handles)
k = 1;
[filename pathname] = uigetfile({'*.*'},'File Selector','MultiSelect', 'on')
iscellstr(filename)
celldata1 = cellstr(pathname)
celldata2 = cellstr(filename)
celldata3 = strcat(celldata1,celldata2)
subplot(3,4,1),imshow(celldata3{1})
subplot(3,4,2),imshow(celldata3{2})
subplot(3,4,3),imshow(celldata3{3})
subplot(3,4,4),imshow(celldata3{4})
subplot(3,4,5),imshow(celldata3{5})
subplot(3,4,6),imshow(celldata3{6})

The reason I asked for the version was that if you were using an older version (than R2014b) you could set the BackgroundColor property of the uipanel to be 'none' which would make it transparent. This "feature" doesn't work in R2014b onwards...
%% Only HG1 (pre R2014b)
f = figure;
subplot ( 3, 3, 4 )
uipanel ( 'parent', f, 'Position', [0. 0. 0.6 0.6], 'BackgroundColor', 'none' );
Im afraid other options will require more knowledge of how GUI's work - specifically creating GUI's from the commandline (and not in GUIDE):
% Create a figure
f = figure;
% Create a uicontainer (this is a way of grouping controls together
uic = uicontainer ( 'parent', f, 'position', [0.1 0.1 0.5 0.5] );
% Create an axes -> which is a child of the UICONTAINER
ax = axes ( 'parent', uic, 'position', [0 0 1 1] );
% Create a uipanel -> which is a chilf of the FIGURE
uipanel ( 'parent', f, 'position', [0 0 0.4 0.7] );
% Some data to plot
image(rand(100)*255,'parent',ax)
% Note at this point the axes is underneath the uipanel
%%
% Hey presto we can move the uicontainer to the top and the axes appears! :)
uistack ( uic, 'top' )
Note: If you create the uicontainer after creating the uipanel then you dont need to use uistack - I put it in that order to show that uistack will move the 'axes' in the stack order...

I'm not sure I've correctly undestood what you need, nevertheless ...
you can first create the panel (uipanel) specifying its position (which includes size), then create as many axes as you need (consider the number of imagery you want to add) in order to crate a sort of chessboard (you can do this by properly setting their position and size).
You can now load the images over the axis by specifying the parent property.
In the following example I create a uipanel which contains three images, notice the coupling "axes-handle - parent property" in the calls to imshow.
In the "pushbutton1_Callback" of your code, you can "automate" this procedure.
uipanel ('position', [0 0 0.33 0.95],'title','PLOK');
a1=axes('position',[0 0 .3 .3])
a2=axes('position',[0 0.3 .3 .3])
a3=axes('position',[0 0.6 .3 .3])
imshow('curva_con_linee_verticali.jpg','parent',a1)
imshow('grafico_3d_assi_cartesiani.jpg','parent',a2)
imshow('prod_punt.jpg','parent',a3)
This is how the Figure looks like (the three graphs are actually three jpg images):
Hope this helps.

Related

MATLAB addlistener with additional arguments in a GUI

I am writing a MATLAB GUI which has an axes to show an image using a push button. I also use impixelinfoval to show the pixel coordinates of the location of the mouse as follows:
h = imshow('hestain.png', 'Parent', handles.axes1);
hp = impixelinfoval(gcf, h);
I can successfully add a listener to the handle of the impixelinfoval with no argument passed to the callback function by:
addlistener(hp, 'String', 'PostSet', #mycallback) % Works
However, I am trying to pass two arguments to the callback function as follows and I have not been successful to pass them to the function. I need handles to store a variable calculated in the callback function as well as hObject to be able to execute guidata(hObject, handles) so that I have access to the new variable in the entire GUI.
addlistener(hp, 'String', 'PostSet', #mycallback1(hObject, handles)) % Does not work
Could someone kindly help me with this problem?
The following is the entire MWE to test this issue:
function varargout = untitled(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', #untitled_OpeningFcn, ...
'gui_OutputFcn', #untitled_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
function untitled_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
function varargout = untitled_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
h = imshow('hestain.png', 'Parent', handles.axes1);
hp = impixelinfoval(gcf, h);
addlistener(hp, 'String', 'PostSet', #mycallback) % Works
% addlistener(hp, 'String', 'PostSet', #mycallback1(hObject, handles)) % Does not work. I would like to pass both hObject and handles to mycallback function.
function mycallback(src, evt)
disp(evt.AffectedObject.String)
function mycallback1(src, evt, hObject, handles)
disp(evt.AffectedObject.String)
% Create a variable and store it in the handles
handles.pixelcoord = evt.AffectedObject.String;
% Update handles
guidata(hObject, handles)
I just ran into your post, since I am facing a similar problem. I am programming an instrument GUI, the instrument is defined as an object that can send notifiers. I want to have the GUI updated with the information on that particular notifier event. To put a long story short, what finally worked for me is the following:
Definition of listener in GUI opening function:
addlistener(handles.Stage, 'PID_changed', #(hObject, eventdata)updatePID_Callback(hObject, eventdata, handles));
Definition of Callback function (regular function, not an object method):
function updatePID_Callback(~,~,handles)
... (updating GUI, e.g., set(handles.editbox1, 'string', num2str(someValue)) ..
end
That's all I can say, hope it helps ..
A listener will by default want to pass 2 default parameters as per your example that works:
addlistener(hp, 'String', 'PostSet', #mycallback() )
You should notice in your function you have 2 inputs:
function mycallback ( src, event )
...
end
What your trying to do is to either:
Add 2 extra arguments
Replace the 2 default arguments with a different 2.
You do this my controlling the callback function:
addlistener(hp, 'String', 'PostSet', #(src,evt)mycallback1(src, evt, hObject, handles))
or
addlistener(hp, 'String', 'PostSet', #(src,evt)mycallback1(hObject, handles))
The above lines are capturing the default callbacks src and evt and the first one is passing them to your callback with your additional variables, the other is not.
edit My answer was focusing on how to call a listener, I dont have the imageprocessing toolbox so cant create a code which uses the impixelinfoval function.
Since your code on its own doesn't run I have created a small example below which shows you how to add listeners which react when a (in this case axes title) string property has been set, it runs on its own so you should be able to run it and see how it works.
function untitled
%%
% create a figure
h = figure;
% create an axes
ax = axes ( 'parent', h );
% create a variable which we will plot
p = peaks(50);
% plot the variable
imagesc ( p, 'parent', ax );
% createa some initial title, x and y lables
t = title ( ax, 'Title' );
x = xlabel ( ax, 'X Label' );
y = ylabel ( ax, 'Y Label' );
% add a callback to run when the mouse moves.
h.WindowButtonMotionFcn = #(a,b)moveMouse (ax, t);
% add listeners which are triggered after the title has been set
% this listener passes the standard callbacks and some extras, namely
% the handles of the title and the y label
addlistener ( t, 'String', 'PostSet', #(h,evt)mycallback1(h,evt,t,y) )
% this listener only passes the handle to the title and the x label
addlistener ( t, 'String', 'PostSet', #(h,evt)mycallback(t,x) )
end
function moveMouse ( ax, t )
% update the title of the axes for
t.String = sprintf ( 'current point %.1f,%.1f', ax.CurrentPoint(1,1:2) );
end
function mycallback ( t, x )
% udpate the x label string
x.String = sprintf ( 'X Label -> title value: %s', t.String );
end
function mycallback1 ( h, event, t, y )
% update the y label string
y.String = sprintf ( 'Y Label -> title value: %s', t.String );
end
This GUI is created from code (not guide).
This works by updating the axes title when the mouse moves to provide the current point. I have added 2 listeners which update the X and Y label strings after the title has been set.
From knowing how to add listeners you should be able to use this theory in your own code, and that might highlight what any remaining errors you have are.
your error message in comment below
addlistener(hp, 'String', 'PostSet', #(source, event, hObject, handles)myImageMagnifier3(source, event, hObject, handles))
I suspect this should be:
addlistener(hp, 'String', 'PostSet', #(source, event)myImageMagnifier3(source, event, hObject, handles))
like in my original example.

Matlab GUI: Problems while using imfreehand()

I have applied Canny edge detection on am image and now want to crop a part of it for further procession. I have created 4 axes with the tags axes1, axes2, axes3 and axes4. I want to display the image first in axes1, then the edge detected again in axes1. Finally the cropped image is to be displayed in axes3 and the image after removal of holes in axes4.
I am including a sample code which recreates the problem:
function varargout = samp_GUI(varargin)
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, 'gui_Singleton', gui_Singleton, 'gui_OpeningFcn', #samp_GUI_OpeningFcn, 'gui_OutputFcn', #samp_GUI_OutputFcn, 'gui_LayoutFcn', [] , 'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before samp_GUI is made visible.
function samp_GUI_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
% --- Outputs from this function are returned to the command line.
function varargout = samp_GUI_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
% --- Executes on button press in browse.
function browse_Callback(hObject, eventdata, handles)
[filename pathname] = uigetfile({'*.jpg';'*.bmp'},'File Selector');
handles.myImage = strcat(pathname, filename);
axes(handles.axes1);
imshow(handles.myImage)
im=imread(handles.myImage);
bw3=im2bw(im,0.3); %threshold value taken as 0.3
BW3=edge(bw3,'canny');
edge_im = BW3;
axes(handles.axes1);
imshow(BW3);
h=imfreehand(handles.axes1);
M=~h.createMask();
I(M) = 0;
axes(handles.axes2);
imshow(I);title('Cropped Image')
I = bwareaopen(I, 50);
axes(handles.axes3);
imshow(I),title('Removed Holes');
% save the updated handles object
guidata(hObject,handles);
When i execute the code in a .m file, it runs perfectly with different images opening in different windows but when the same code is run for the GUI, blank images are problems. I do not seem understand where the problem lies.
I think that you're suffering from some form of copy/paste issue. If you look at the line in your code where I(M) = 0 this doesn't really make sense (given your example) since I is not defined.
MATLAB will not throw any errors at this point though, because it's perfectly valid to create a matrix in this way; however, doing so actually produces a row vector rather than the image you're wanting.
>> M = logical(eye(100));
>> size(M)
ans =
100 100
>> clear I
>> I(M) = 0;
>> size(I)
ans =
1 10000
I imagine what you wanted to do was to apply the mask to your image (im) in which case you should get what you want. I have provided an example below (not sure what you're trying to display in axes1).
load mri
img = double(D(:,:,12));
im = img ./ max(img(:));
figure
handles.axes1 = subplot(2,2,1);
handles.axes2 = subplot(2,2,2);
handles.axes3 = subplot(2,2,3);
handles.axes4 = subplot(2,2,4);
bw3=im2bw(im,0.3); %threshold value taken as 0.3
BW3=edge(bw3,'canny');
edge_im = BW3;
axes(handles.axes1);
imshow(BW3);
h=imfreehand(handles.axes1);
M=~h.createMask();
% Assign im to I to ensure proper cropping.
I = im;
I(M) = 0;
axes(handles.axes3);
imshow(I);title('Cropped Image')
M_noholes = bwareaopen(M, 50);
I(M_noholes) = 0;
axes(handles.axes4);
imshow(I),title('Removed Holes');
If you provide more information it will be easier to help you figure out what you need.

GUI Axes Handle Hold On/Off Not Working Within Callback Function - Matlab

Firstly, programatically, I created and axes object, then an empty scatter which is subsequently populated with data from within another callback function named guiList which works fine. However, as my title states, I cannot seem to be able to get the hold function to work when I pass my axes_h handle into my callback function 'guiHold`.
Here is my scripted code for axes and scatter:
%% create empty scatter plot with panel
e_panel_position = [0.1 0.3 0.5 0.6];
e_panel_h = uipanel('Parent', fig_h, 'Title','Emotion','FontSize',12,'FontWeight', 'bold','BackgroundColor','white','Position',e_panel_position);
axes_position = [0.15 0.12 0.7 0.8];
axes_h = axes('Parent', e_panel_h, 'Position', axes_position);
scatter_h = scatter(axes_h, [],[], 'MarkerEdgeColor',[0 .5 .5], 'MarkerFaceColor',[0 .7 .7],'LineWidth',1.5);
axis(axes_h, [-4 4 -4 4]);
xlabel(axes_h, 'Valence', 'FontSize', 12); % 'FontWeight', 'bold'
ylabel(axes_h, 'Arousal', 'FontSize', 12);
grid on
box on
Here is my guiHold function:
function guiHold(hold_toggle_h, evt, axes_h)
button_state = get(hold_toggle_h,'Value');
if button_state == 1
hold(axes_h, 'on')
%hold on
elseif button_state == 0
hold(axes_h, 'off')
%holf off
end
end
As you may see, I have tried alternative versions of hold to try and make this
happen.
guiHold is being invoked with a GUI toggle button.
EDIT:
Here is my guiList function that is invoked when you select an item from my list_h handle:
function guiList(list_h, evt, scatter_h)
global predict_valence
global predict_arousal
val = get(list_h, 'value');
a = 100;
x = predict_valence;
y = predict_arousal;
N = length(predict_valence);
for i=1:N
if i == val
set(scatter_h, 'XData', x(i), 'YData', y(i), 'SizeData', a);
end
end
end

how to send data from a function out GUI matlab to function GUI.m

How can I pass values (x_locate, y_locate) for a static text in my GUI?
Because the function is out functions generated by the GUI. I'm not achieving to configure the set() function.
I believe it is using handles, but I've tried everything and failed.
to simplify I rewrote the code:
![enter image description here][1]
The "Locations.fig" have: 1 axes, 1 pushbutton and 2 static text.
ctrl+C
function varargout = Locations(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', #Locations_OpeningFcn, ...
'gui_OutputFcn', #Locations_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
function Locations_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
function varargout = Locations_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
function pushbutton1_Callback(hObject, eventdata, handles)
cla(handles.axes1,'reset');
axes(handles.axes1);
image = imread('eight.tif');
im = imagesc(image);
set(im,'ButtonDownFcn', #clique);
function clique (gcbo,eventdata,handles)
pos = get(gca, 'currentpoint');
x_locate = round(pos(1))
y_locate = round(pos(3)) % until here working!!!
set(handles.text1, 'string', ['x loc:' num2str(x_locate)]); %don´t working
set(handles.text2, 'string', ['y loc:' num2str(y_locate)]); %don´t working
Only callbacks set through GUIDE (or some other custom means) receive the extra handles argument. Otherwise, you'll need to retrieve the handles structure manually within the clique function:
handles = guidata(<object>);
The question of what <object> is depends on your GUI setup. If im is a child of the GUI figure, then gcbo1 will do. If it's in a separate figure, then you'll need to get a handle to the GUI figure. Using findobj to either enumerate all figures or search for some specific property of your GUI figure is the straightforward way to do it.
For example, all Handle Graphics objects have a 'Tag' property that you are free to use, which would be helpful in this case. In GUIDE, set the Tag property on your GUI figure to 'my GUI', then you can retrieve the data from anywhere like so:
hfig = findobj('Tag','my GUI');
handles = guidata(hfig);
[1] Incidentally, giving variables the same name as built-in functions isn't a great idea
Set the ButtonDownFcn to be:
set(im, 'ButtonDownFcn', #(src,evt)clique(src,evt,handles))
The Notlikethat resolved the problem! Thanks!!!
so:
x_locate = round(pos(1));
y_locate = round(pos(3)); % until here working!!!
hfig1 = findobj('Tag','text1');
handles = guidata(hfig1);
hfig2 = findobj('tag','text2');
handles = guidata(hfig2);
set(handles.text1, 'string', ['x loc:' num2str(x_locate)]);
set(handles.text2, 'string', ['y loc:' num2str(y_locate)]);
finalized

Import figures to MATLAB GUI using handles?

How can I literally take these figures and place them in the axes windows of my GUI?
I am not sure where to place handles in my user-defined code in the example below. I have 4 figures in total which look similar to this example. I want the 4 figures to be displayed in my GUI window and not in separate windows, so i've created 4 axes windows in the .fig file.
The code for this particular figure draws a grid of 66 black and white rectangles based on whether or not a value in MyVariable is a 1 or a 0. Black if MyVariable is a 1, White if MyVariable is 0. I have a file for my .fig GUI, one file to control the GUI and one with user-defined code that links to the GUI.
function test = MyScript(handles)
lots of code in between
% Initialize and clear plot window
figure(2); clf;
% Plot the west wall array panels depending on whether or not they are
% shaded or unshaded
for x = 1:11
for y = 1:6
if (MyVariable(x,y) == 1)
rectangle('position', [x-1, y-1, 1, 1] ,'EdgeColor', 'w', 'facecolor', 'k')
else if(MyVariable(x,y) == 0)
rectangle('position', [x-1, y-1, 1, 1], 'facecolor', 'w')
end
end
end
end
title('West Wall Array',...
'FontWeight','bold')
axis off
The figure for the above code looks like this:
The function definition contains all of my script code for all 4 plots because I didn't partition my script into individual functions earlier on.
My GUI script code contains:
MyScript(handles);
As DMR sais, it's necesary to set the 'CurrentAxes'. For example, if you want to plot into the axis with the tag name 'axis1' you should simply add:
axes(handles.axes1);
to your code. Below is a very simple example for a figure containing a 'axis1' and 'axis2' using your code (corrected) code from above. Im not really shure wether you want to plot on an axis on your gui itself or a separate figure. I hope I covered both cases.
function varargout = Test(varargin)
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', #Test_OpeningFcn, ...
'gui_OutputFcn', #Test_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before Test is made visible.
function Test_OpeningFcn(hObject, eventdata, handles, varargin)
% Choose default command line output for Test
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
plot(handles.axes2,-2*pi:0.1:2*pi,sin(-2*pi:0.1:2*pi));
% Initialize and clear plot window
MyVariable = ones(11,6);
MyVariable(1:5,1) = 0;
axes(handles.axes1);
for x = 1:11
for y = 1:6
if (MyVariable(x,y) == 1)
rectangle('position', [x-1, y-1, 1, 1] ,'EdgeColor', 'w', 'facecolor', 'k');
elseif(MyVariable(x,y) == 0)
rectangle('position', [x-1, y-1, 1, 1], 'facecolor', 'w');
end
end
end
title('West Wall Array',...
'FontWeight','bold')
figure(2); clf;
for x = 1:11
for y = 1:6
if (MyVariable(x,y) == 1)
rectangle('position', [x-1, y-1, 1, 1] ,'EdgeColor', 'w', 'facecolor', 'k');
elseif(MyVariable(x,y) == 0)
rectangle('position', [x-1, y-1, 1, 1], 'facecolor', 'w');
end
end
end
title('West Wall Array',...
'FontWeight','bold')
function varargout = Test_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
Your guide GUI should look like this:
And your result like this:
You can set the axis to plot into prior each plot command by setting the 'CurrentAxes' property of the figure.
Within GUIDE, you can tag a given axis, for example: http://www.mathworks.com/help/matlab/creating_guis/gui-with-multiple-axes-guide.html . Then within your drawing code, indicate which axis should be plotted into via the 'set' function and 'CurrentAxes' property.
A simple example is below, though it doesn't use GUIDE, only basic subplot axis handles:
% plots in most recent axis by default (ax2)
fig = figure;
ax1 = subplot(1,2,1);
ax2 = subplot(1,2,2);
plot(rand(1,10));
% indicate that you want to plot in ax1 instead
fig = figure;
ax1 = subplot(1,2,1);
ax2 = subplot(1,2,2);
set(gcf, 'CurrentAxes', ax1);
plot(rand(1,10));