MATLAB GUI handles - matlab

I have question about using "handles" in Matlab Callback function.
I don t know how to use the same thing twice. Please help me.
So,I build Matlab GUI and I have callback function for upload image:
function pushbutton2_Callback(hObject, eventdata, handles)
handles = guidata(hObject);
[filename pathname]=uigetfile({'*.jpg';'*.bmp'},'File Selector');
image=strcat(pathname, filename)
handles.data1=imread(image)
axes(handles.axes1);
imshow(handles.data1);
set(handles.edit1,'string',filename)
set(handles.edit2,'string',pathname)
guidata(hObject, handles);
,and I have callback fuction for converting the same image to "Gray Scale":
function Gray_Callback(hObject, eventdata, handles)
handles = guidata(hObject);
axes(handles.axes2);
img=handles.data1;
x=imread(img);
y=rgb2gray(x); %function to convert an rgb image to gray scale
imshow (y)
guidata(hObject, handles);
,but it doesn't work.
Does anyone know what I'm doing wrong?

Your first function says
handles.data1=imread(image)
Then your second function says
img=handles.data1;
x=imread(img);
Since img contains image data, not the name of a file, what does imread(img) mean?
I presume you want to work directly with the image data img here, not use imread at all.

Related

GUI in matlab, loop of images in axes

So I'm building a classifier of images. In the GUI a image loads and insert a value on a text box, and push a button. I'm having a problem loading the image in the axes. Because when the axes function is called the handles is zero(due to:% handles empty - handles not created until after all CreateFcns called). And my problem is, how do I get to just call one image at a time for the axes.
The ideal solution, is I create a handles.images=imagedatastore, and every time I push the button I add to a counter(which I already have made) and then that give the indices to get the image from the datastore. My problem with this is that I can't get the first picture, because in the beginning the handles are empty. I have made the callfunction for the axes:
% --- Executes during object creation, after setting all properties.
function axes1_CreateFcn(hObject, eventdata, handles)
% hObject handle to axes1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
[pict_croped,Nphotos,Date_img] =getcropedimagages;
handles.img =pict_croped;
i=readimage(handles.img,1);
% axes(hObject)
imshow(i)
% Hint: place code in OpeningFcn to populate axes1
but this has two problems, first, I don't really want to call the function that creates the datastore all the time I push the button, second, I still can't get the indice of the counter to be in the function,if I have:
i=readimage(handles.img,handles.counter)
it will give me the error in the first time, of not having handles.counter
Any idea how to solve this?This is the first GUI I'm building.
The issue is very clearly in the comment that GUIDE provides for you. The handles struct isn't populated until all CreateFcn have been run so you'll want to use the OpeningFcn to do any initialization of the graphics objects. You can then add any data you need to the handles struct and save it using guidata so that it's available from within all of your other callback functions.
function OpeningFcn(hObject, eventData, handles)
[pict_croped,Nphotos,Date_img] = getcropedimagages;
handles.img = pict_croped;
i = readimage(handles.img,1);
imshow(i, 'Parent', handles.haxes1)
% "Save" the changes to the handles object
guidata(hObject, handles)
Well, I end up with:
in the opening fucntion:
i = readimage(handles.img,handles.counter);
imshow(, 'Parent', handles.axes1)
and in the button call back:
i = readimage(handles.img,handles.counter);
imshow(i, 'Parent', handles.axes1)
inthe end is a very simple solution, I think I was just mind blocked over the first iteration...

How to determine if mouse is over axes using MATLAB GUIDE

I know this question has been asked before, but I can't find any good answers. I keep stumbling upon WindowButtonMotionFcn, but I don't really understand how to use it. In my program I want to be able to click and store coordinates ONLY when the user is above a certain axes, so that the normal mouse appears for the rest of the GUI and they can play with other buttons. Thanks for any insight.
I would recommend not using WindowButtonMotionFcn and instead use the ButtonDownFcn of your axes object. This way MATLAB takes care of your hit detection for you.
For example:
function testcode()
h.myfig = figure;
h.myaxes = axes( ...
'Parent', h.myfig, ...
'Units', 'Normalized', ...
'Position', [0.5 0.1 0.4 0.8], ...
'ButtonDownFcn', #myclick ...
);
end
function myclick(~, eventdata)
fprintf('X: %f Y: %f Z: %f\n', eventdata.IntersectionPoint);
% Insert data capture & storage here
end
Prints your coordinate every time you click inside the axes but does nothing when you click anywhere else.
EDIT:
Since this is a GUIDE GUI the easiest approach is to utilize getappdata to pass data around the GUI. To start, you need to modify your GUI_OpeningFcn to something like the following:
function testgui_OpeningFcn(hObject, eventdata, handles, varargin)
% Choose default command line output for testgui
handles.output = hObject;
% Initialize axes click behavior and data storage
set(handles.axes1, 'ButtonDownFcn', {#clickdisplay, handles}); % Set the axes click handling to the clickdisplay function and pass the handles
mydata.clickcoordinates = []; % Initialize data array
setappdata(handles.figure1, 'mydata', mydata); % Save data array to main figure
% Update handles structure
guidata(hObject, handles);
And then add a click handling function elsewhere in your GUI:
function clickdisplay(~, eventdata, handles)
mydata = getappdata(handles.figure1, 'mydata'); % Pull data from main figure
mydata.clickcoordinates = vertcat(mydata.clickcoordinates, eventdata.IntersectionPoint); % Add coordinates onto the end of existing array
setappdata(handles.figure1, 'mydata', mydata); % Save data back to main figure
You can then pull the array into any other callback using the same getappdata call.

pass filename to gui to show image

I have a gui which already has axes on it...i want to pass a filename to that gui and display it on the axes...here's how i tried it..this is written in an xyz.m file:
close current_gui;
result_image(im2fn);
here, current gui is a gui i was working with and result_image is the gui where i want to show the image, im2fn is a variable having the filename of the image...
In result_gui i wrote the following code..
function result_image_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
axes(handles.axes1);
imshow(im2fn);
The gui is displayed but there is no image shown and also i get an error as Undefined function or variable 'im2fn'....Please Help!!
You are receiving this error because im2fn is not part of the local workspace inside OpeningFcn - you have made an incorrect assumption about the way varargin works. When you use varargin, it will be a cell array of the values you passed. See the link for more examples, but in your case you just want to do something like this:
% Make sure the user passed us something to display
assert(~isempty(varargin), [mfilename ':NoImageToDisplay'], 'You must pass an image to the ''result_image'' GUI');
% Extract data from varargs
im2fn = varargin{1};
% Show it!
imshow(im2fn);

Editing one function in GUIDE, changes all functions?

I am using Matlab's GUIDE for the first time, I am trying to edit one of the two push button functions (both open an image), but editing one changes all of them. Here is a bit of code:
% --- Executes on button press in Floating.
function Floating_Callback(hObject, eventdata, handles)
clc;
axes(handles.axes1);
[Float, PathName, FilterIndex] = uigetfile('*.bmp');
if(Float ~= 0)
Floating = fullfile(PathName, Float);
FloatArray = imread(Floating);
imshow(FloatArray);
axis on;
end
% Update handles structure
guidata(hObject, handles);
% hObject handle to Floating (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% --- Executes on button press in Reference.
function Reference_Callback(hObject, eventdata, handles)
clc;
axes(handles.axes2);
[Ref, PathName, FilterIndex] = uigetfile('*.bmp');
if(Ref ~= 0)
Reference = fullfile(PathName, Ref);
ReferenceArray = imread(Reference);
image(ReferenceArray);
end
% Update handles structure
guidata(hObject, handles);
For example,
image(ReferenceArray)
will open an image in RBG, but
imshow(FloatArray)
will open in grayscale (I also do not understand why that is). But my main concern is after opening up
imshow(FloatArray)
the other image will automatically turn grayscale. I am very confused... Also, as far as I know the images ARE already grayscale, at least they are when I open them in MS paint or ImageJ.
It would be better to explicitly specify the parent handle whenever you are doing GUI stuff. For example:
imshow(img, 'Parent',handles.ax1)
and
axis(handles.ax1, 'on')
As for images and colormaps, you should understand the type of images MATLAB supports (indexed vs. truecolor). Also note that a figure has only one colormap applied to all images, although there are techniques to overcome this.

How do I add my own variables to the handles structure from within a custom function of mine?

I have a question to ask the MATLAB gurus here ..
So here is my code (only showing lines of code which are relevant to the problem here):
mainProcess(hObject, handles)
handles.Checkpoint2 =1;
guidata(hObject, handles);
function testGUI1_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
handles.Checkpoint1 = 1;
mainProcess(hObject, handles);
handles.Checkpoint3 = 1; //EDIT: Checkpoint2 is also not visible at this line
guidata(hObject, handles);
handles.Checkpoint4 = 1;
function saveAndContinueButton_Callback(hObject, eventdata, handles)
(breakpoint here) --> faceDatabase(handles.currentImageIteration).lookingTowardsCamera=handles.lookingAtCamera;
So in the above code, I'm making these 'checkpoints' at different parts of the code, and seeing which of them are visible when a save and continue button is clicked separately ...
Checkpoint1 is created BEFORE calling my custom function called mainProcess, Checkpoint2 is created within the code of mainProcess, and Checkpoint3 is created AFTER mainProcess is finished executing and the control is back with the function that called it, which is testGUI1_OpeningFcn ... And Checkpoint4 is created WITHIN testGUI1_OpeningFcn, but AFTER the handles structure is updated in the testGUI1_OpeningFcn code ..
So my question is this, when the button is clicked and I see what is visible at that point, Checkpoint 1 and 3 are visible to the button Callback code, but Checkpoints 2 and 4 are NOT visible ... I understand that Checkpoint4 is not visible because it was created AFTER the handles structure was updated in testGUI1_OpeningFcn's code ... But why is Checkpoint2 not visible, even when at the end of mainProcess's code, I did put a line:
guidata(hObject, handles);
I mean the mainProcess function is getting references to both hObject and handles, so it should have write access to it, right ?
So why isn't Checkpoint2 not visible to the button's Callback code .. ?
Any clues ?
EDIT: I just tried to see if Checkpoint2 is visible even within mainProcess's calling function, right after the control is returned the caller, and even there Checkpoint2 is not visible (see the EDIT in the code above) ..
That's correct, you need to call guidata to update the handles variable you have. However, guidata needs an argument. I think the right command would be:
handles = guidata(hObject);
You may find this link helpful:
http://www.mathworks.com/matlabcentral/answers/10197-guidata-doesn-t-work-the-way-i-expected-it-to
I believe you need to add the following just after calling mainProcess()
handles = guidata();
In general, the 'handles' struct is passed by value to the guidata() function. Therefore, mainProcess() cannot change the handles structure -- just attach the existing structure to the handle. Before making further modifications you need to get it back (using handles=guidata()), update it and set it again with guidata(h, handles).
Let me know if this is not clear enough (or just does not work :)
Edit
You need to change the code like this:
function testGUI1_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
handles.Checkpoint1 = 1;
mainProcess(hObject, handles);
handles = guidata(); // <--- new line
handles.Checkpoint3 = 1; //EDIT: now checkpoint2 will be visible here
guidata(hObject, handles);
handles.Checkpoint4 = 1;
guidata(hObject, handles); // Otherwise Checkpoint4 will not be bound to hObject