matlab gui - draw points and lines on image - matlab

I'm trying to do in matlab, GUI that the the user enters points and connection between them. he also enters a map photo(png image) and scale for the axes(axe x will be from 0 to scale).
At the end(after he enters all the input) I want to show the user the image with all the nodes and connection on it.
I have 5 matlab files - screen1.m, screen2.m, screen3.m, screen4.m, globalParams.m
in globalParams I have global params so I can use them from screen GUI to screen GUI. in screen1 the user enters the number of nodes(for example 5), and also he enters the map. when he press the Next button the callback function calls "screen2();". in screen2.m the user enters the (x,y) coordiante and when he press the Next button the callback function calls "screen3();".
in screen3 the user update all the connections between all the nodes. when finishes he press the Finish button and the callback function calls "screen4". in screen4 I added in the GUI axes and there I did "imshow"..
but the real thing that I want to do is to change the axes to be from 0 to scale(instead of 0 to 1), I want also to put the image(I did it with imshow), and the last and the most important thing I want to put on the image is the nodes and the lines between them(if the user add connection between node i to node j so in the image will be a line between them. maybe to put the lines and the nodes with diffrent colors so we can distinguish the lines and the nodes)
in screen4 we have: xNodes and yNodes- 2 arrays for nodes "x" and "y" axes.((xNodes(1),yNodes(1) is node1 place). Also we have Scale and fullPathName for the image name. we have also hopsMatrix it's 2D array- if hopsMatrix(i,j)=1 there is a connection between i to j.
some code:
in screen1, the upload image and numOfNodes and scale:
% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global fullPathName;
[fileName pathName] = uigetfile({'*.png'},'File Selector');
fullPathName = strcat(pathName, fileName);
imshow(fullPathName);
% --- Executes on button press in pushbutton1.
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)
global numOfNodes;
global scale;
scale = str2num(get(handles.edit1, 'string'));
numOfNodes = str2num(get(handles.edit2, 'string'));
in screen4, where I have all the inputs and I want to put the nodes in the map(I dont know how to do it, so for now this is the code):
% --- Executes just before screen4 is made visible.
function screen4_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 screen4 (see VARARGIN)
global fullPathName;
global xNodes;
global yNodes;
global scale;
global hopsMatrix;
img = imread(fullPathName);
imshow(fullPathName);

this is a solution someone gave me.. I'll share it
% --- Executes just before screen4 is made visible.
function screen4_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 screen4 (see VARARGIN)
global fullPathName;
imshow(fullPathName);
global xNodes;
global yNodes;
global scale;
global hopsMatrix;
x_original=get(handles.axes1,'xlim');
y_original=get(handles.axes1,'ylim');
min_lim=min(x_original(2),y_original(2));
max_lim=max(x_original(1),y_original(1));
xlim([max_lim,min_lim])
ylim([max_lim,min_lim])
dist=min_lim-max_lim;
set(handles.axes1)
hold on
plot((xNodes(:,1))*dist/scale+x_original(1),min_lim+y_original(1)-(yNodes(:,1))*dist/scale,'rx','markersize',8,'linewidth',2)
[row,col] = find(hopsMatrix);
for i=1:length(row)
plot((xNodes([row(i),1;col(i),1]))*dist/scale+x_original(1),min_lim+y_original(1)-(yNodes([row(i),1;col(i),1]))*dist/scale,'k','linewidth',2)
end

Related

MATLAB - passing new value of parameter from GUI into .m script

I want to make simple GUI for my script, where I can edit parameter values and running that script.
I've created example scipt and GUI with 2 buttons. I'cant put script code into GUI code, I will need to aply it on much larger script.
So, script code:
number = 10;
variable(1:10) = NaN;
for i = 1:10;
variable(i) = i * number;
end
figure
plot(variable)
Push button code, that is working fine. script is name of .m file, not function:
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)
evalin('base','script')
But I dont know what to type into edit button code If i want to change value of "number" in the script:
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)
% Hints: get(hObject,'String') returns contents of edit1 as text
% str2double(get(hObject,'String')) returns contents of edit1 as a double
And last thing, sometimes when I try to plot more graphs, one figure overwrites GUI figure and I can see only buttons, but not whole GUI.
Thank you fot any help.
The hint given in the last piece of code is enough.
a = str2double(get(hObject,'String'));
This will save the input value as a double, in the callback function's stack.
In order to pass this value to the caller script's (base) stack, use assignin
assignin('base', 'number', a)

GUI Workflow command

I am developing a GUI in Matlab and I would like to know which is the workflow when you click a button. Being more specific, I would like to know 'what happens' when I click a button, because its callback is not triggered.
If you are using GUIDE for developing, every time you add a button to your GUI a chunk of code is generated:
% --- Executes on button press in pushbutton1.
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)
This function is called every time you push the said button. So, if you need something to be executed when you click the button you just need to add the lines of code you want to execute below that generated chunk of code. For example, imagine you have an edit text variable called edit1 with value
edit1 = 'hello';
If you want to interact with it you need to call handles, but first you need to create a global variable:
%set the current figure handle to main application data
setappdata(0,'figureHandle',gcf);
%set the handles to figure's application data
setappdata(gcf,'EDIT1',handles.edit1);
Then, in the callback function of your button you need write the following:
% --- Executes on button press in pushbutton1.
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)
figureHandle = getappdata(0,'figureHandle');
EDIT1 = getappdata(figureHandle,'EDIT1 ');
new_string = 'updated string';
set(EDIT1, 'String', new_string);
Hope this helps

Making universal variables in MATLAB GUI

I'm kind of new to MATLAB and I'm doing some experiments for a school project.
What I want is a GUI with 3 buttons, when you press either of the first two, it adds up to one on a variable (one variable for each button), and when you press the third button, it does something with the variables from the first two buttons.
I used "guide" and dragged and dropped the buttons, and then I modified the functions.
But I realized that my variables only exist inside the function for the button, so if I initialize them they would restart everytime I press the button, and also there is no way for my third button to know the value of the first two.
Is there a way to make this variables always present? Or pass them from a function to another?
My code it's just the automatic code generated by "guide", with a v1 = v1+1; in the first button callback function and v2 = v2+1 in the second one, and disp(v1) disp(v2) in the third.
I hope you understand what I mean, I'm not a native english speaker so...
Anyway, thanks a lot, hope it's something easy to fix.
You have several options:
use global variables as nhowe suggested. But using global variables is not a good practice: see Top 10 MATLAB code practices that make me cry, or Wikipedia article
use setappdata / getappdata functions to store your variables (this is the simpler one)
learn how to use and properly update the handles structure that appears in each callback function for GUI controls created in GUIDE (this one is more complicated).
Here is an example of *.m file for case #3. Most of GUIDE-generated code was removed showing only things related to your variables. Basically, you have to update the handles structure in each callback function that does some changes to it with guidata(hObject, handles); line. After this all subsequent callbacks will see the updated handles structure.
function varargout = GUIProgramWithVariables(varargin)
% Here goes some comment from GUIDE
% Begin initialization code - DO NOT EDIT
% . . . actual code skipped
% End initialization code - DO NOT EDIT
% --- Executes just before GUIProgramWithVariables is made visible.
function GUIProgramWithVariables_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 GUIProgramWithVariables (see VARARGIN)
% Choose default command line output for GUIProgramWithVariables
handles.output = hObject;
% Here your code starts. It should be at the end of OpeningFcn
% Add your fields to handles structure
handles.C1 = 1;
handles.C2 = 2;
handles.C3 = 3;
% this updates modified handles structure
% so all subsequent call-backs will see the changes
guidata(hObject, handles);
% --- Executes on button press in Button1
function Button1_Callback(hObject, eventdata, handles)
% hObject handle to BrowseButton (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Here we do the magic with Button1
handles.C1 = handles.C1 + 1;
% this updates modified handles structure
% so all subsequent call-backs will see the changes
guidata(hObject, handles);
% --- Executes on button press in Button2
function Button1_Callback(hObject, eventdata, handles)
% hObject handle to BrowseButton (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Here we do the magic with Button2
handles.C2 = handles.C2 + 1;
% this updates modified handles structure
% so all subsequent call-backs will see the changes
guidata(hObject, handles);
% --- Executes on button press in Button3
function Button3_Callback(hObject, eventdata, handles)
% hObject handle to BrowseButton (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Here we do the magic with Button3
handles.C3 = handles.C1 + handles.C2;
% this updates modified handles structure
% so all subsequent call-backs will see the changes
guidata(hObject, handles);
The following is not the best practice for large complicated programs, but for something simple like what you're trying to do it sounds like global variables would be perfect. Say that X, Y, and Z are the variables you want to share between functions. Add the following at the beginning of every function that uses them, and they will all have access to the same values.
global X Y Z

MATLAB, GUIDE, viewing the slice number on a dicom stack

I want to view the number of the slice that I'm examining via a simple previous/next slice GUI. I store number of the slice that I'm viewing on handles.index and I'm able to update it via the previous, next pushbuttons.
I wrote the following on the edit text callback function:
function edit2_Callback(hObject, eventdata, handles)
handles.output=hObject
set (edit2.handles,'Tag', handles.index); %also tried with the 'String' property and failed
The Property is not updating when the code is running. It remains as 'Edit Text', what's wrong here?
Full Code, Dicom file
Duh, I made the update on the pushbutton callbacks, and it works fine :)
% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
handles.output = hObject;
handles.index = handles.index+1;
Cek (hObject, eventdata, handles);
imshow(handles.image_data(:,:,handles.index),'DisplayRange',[]);
set (handles.edit2,'String', handles.index);

Getting snapshot from webcam in Matlab

I have created a simple GUI to preview webcam stream and to get snapshot from it. For this I have created on axes to show video, one push button(pushbutton1) to start preview, one push button(pushbutton2) to get snapshot. Following is the code for these two push buttons.
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)
axes(handles.axes1);
vidObj = videoinput('winvideo',1);
videoRes = get(vidObj, 'VideoResolution');
numberOfBands = get(vidObj, 'NumberOfBands');
handleToImage = image( zeros([videoRes(2), videoRes(1), numberOfBands], 'uint8') );
preview(vidObj, handleToImage);
% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
a=getsnapshot(get(axes,'Children'));
imshow(a);
In pushbutton2_Callback I am trying to get child of axes ie. vidObj. But this gives me error ??? Undefined function or method 'getsnapshot' for input arguments of type 'double'.. Why is it returing double type instead of child object vidObj?
How can I fix it and get snapshot?
Is there any other better way?
(I just started learning GUI.)
Thanks.
A better alternative to declaring your variables global, is to use the handles structure for sharing data. GUIDE already uses this structure to store handles to all GUI components. Simply add your data as a field to this structure that gets passed around to all callback functions.
So inside the first callback:
function pushbutton1_Callback(hObject, eventdata, handles)
%# ... your existing code ...
%# store video object in handles, and persist
handles.vidObj = vidObj;
guidata(hObject,handles)
end
Then in the second, you can retrieve the video object from the handles structure:
function pushbutton2_Callback(hObject, eventdata, handles)
frame = getsnapshot(handles.vidObj);
imshow(frame);
end