I have been trying to show an image after browsing it. However, I have been getting errors like:
??? Reference to non-existent field 'axes1'.
Error in ==> ImGui>Browse_Callback at 19
axes(handles.axes1)
??? Error while evaluating uicontrol Callback
I have tried working with both predefined axes [like 'axes(handles.axes1);'] as well as with post-defined [like 'imshow(imgorg, 'Parent', handles.axes1);']. Unfortunately, both techniques have not worked out for me and I am consistently stuck with axes. I also tried making a customized axes and work with that but it also failed to show my image on the figure. Can anyone please identify/ rectify the problem in my code:
function ImGui
f =figure('Visible','on','Position',[460,200,700,385]);
BrowseBt = uicontrol('Style','pushbutton',...
'String','Browse','Position',[600,350,70,25],...
'Callback',#Browse_Callback);
dispnames = uicontrol('Style','text','String','',...
'Position',[50,350,400,20]);
movegui(f,'center');
function Browse_Callback(hObject, eventdata, handles)
handles.output = hObject;
[FileName,PathName] = uigetfile('*.jpg;*.png','Select an image file',...
'C:\Users\owner\Downloads\Conjunctiva\SGRH');
fpname = strcat(PathName,FileName);
dispnames = uicontrol('Style','text','String',fpname,...
'Position',[50,350,400,20]);
imgorg = imread(fpname);
handles.output = hObject;
guidata(hObject, handles);
axes(handles.axes1);
imshow(imgorg);
% ImAxes = axes('Parent', f, ...
% 'Units', 'normalized', ...
% 'position',[50 50 400 250]);
% 'HandleVisibility','callback', ...
% imshow(imgorg, 'Parent', handles.axes1);
% imshow(imgorg, 'Parent', handles.ImAxes);
end
end
Use the guidata function.
and reorganize your code a little bit
You define all your uicontrols (button, textbox, axes etc ...) and you assign their handle to a structure (called handles here). Then when you GUI is fully defined, call guidata to store this handle structure in a place where any callback can access it.
Then in your callback function, call guidata again to retrieve this handle structure and get access to your objects (you axes and your textbox).
function ImGui
f =figure('Visible','on','Position',[460,200,700,385]);
handles.BrowseBt = uicontrol('Style','pushbutton',...
'String','Browse','Position',[600,350,70,25],...
'Callback',#Browse_Callback);
handles.dispnames = uicontrol('Style','text','String','',...
'Position',[50,350,400,20]);
handles.ImAxes = axes('Parent', f, ...
'Units', 'pixels', ...
'position',[30 30 640 300],...
'visible','off');
movegui(f,'center');
guidata(f,handles) ;
function Browse_Callback(hObject, eventdata)
handles = guidata(hObject);
[FileName,PathName] = uigetfile('*.jpg;*.png','Select an image file');
fpname = strcat(PathName,FileName);
imgorg = imread(fpname);
set(handles.dispnames,'String',FileName)
set(handles.ImAxes,'visible','on') ;
imshow(imgorg, 'Parent', handles.ImAxes);
guidata(hObject, handles);
end
end
In this specific case you don't really need to call guidata again at the end of the callback to store the values again but it is good practice, in case you modified something you want the changes to be saved.
Related
I have a GUI as shown below:
And I would like to apply Otsu threshold on the image displayed after contrast enhancement. But whenever I pressed the apply button for Otsu threshold,the Otsu threshold will be applied on the original image instead of the image after contrast enhancement (refer to the attached GUI and coding). So how do I overcome this problem?
function pushbutton10_Callback(hObject, eventdata, handles)
I = im2double(handles.im);
imshow(I);
% prompts for the two inputs
prompt = {'Enter LOW contrast limit:','Enter HIGH contrast limit:'};
% title of the dialog box
dlg_title = 'Input';
% number of input lines available for each variable
num_lines = 1;
% default answer for each input
defaultans = {'0','1'};
% generate the dialog box and wait for answer
answer = inputdlg(prompt,dlg_title,num_lines,defaultans);
% convert string answers into doubles
lo_in = str2double(answer{1});
hi_in = str2double(answer{2});
% apply on image
K = imadjust(I,[lo_in hi_in],[]);
axes(handles.axes2);
imshow(K);
axes(handles.axes3);
imshow(K);
function pushbutton12_Callback(hObject, eventdata, handles)
I = im2double(handles.im);
im = rgb2gray(I);
level = graythresh(im)
a = im2bw(im,level);
axes(handles.axes3);
imshow(a);
axes(handles.axes4);
imshow(a);
I think it better to define some field for handles structure in openingFcn function like below
handles.OriginaImage=0;
handles.afterEnhancement=0;
and when you read Original Image you update handles.OriginalImage as following code
handles.OriginalImage=imread("whatever.whatever");
% don't forget below line because this line update handles structure
guidata(hObject,handles)
and when you apply contrast Enhancement you save it in handles.afterEnhancement and again update handles structure
lo_in = str2double(answer{1});
hi_in = str2double(answer{2});
% apply on image
handles.afterEnhancement = imadjust(handles.OriginalImage,[lo_in hi_in],[]);
guidata(hObject,handles)
then in pushbutton12_callback you can apply otsu method on Enhancement image by handles.afterEnhancement
I = im2double(handles.afterEnhancement);
im = rgb2gray(I);
level = graythresh(im)
a = im2bw(im,level);
axes(handles.axes3);
imshow(a);
I test this codes in my MATLABin my way
Example code
function varargout = Sdfl(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', #Sdfl_OpeningFcn, ...
'gui_OutputFcn', #Sdfl_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 Sdfl_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
handles.original_image=0;
handles.blur_image=0;
% Update handles structure
guidata(hObject, handles);
function varargout = Sdfl_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
function pushbutton1_Callback(hObject, eventdata, handles)
handles.original_image=imread('pout.tif');
guidata(hObject, handles); %this line will update handles structure
axes(handles.axes1)
imshow(handles.original_image)
function pushbutton2_Callback(hObject, eventdata, handles)
handles.blur_image=imadjust(im2double(handles.original_image),[0.3 0.7],[]);
guidata(hObject, handles);
axes(handles.axes2)
imshow(handles.blur_image);
function pushbutton3_Callback(hObject, eventdata, handles)
thresh=graythresh(handles.blur_image);
bw_image=im2bw(handles.blur_image,thresh);
axes(handles.axes3)
imshow(bw_image);
output
I want to play my wav on percussion background image area with my pushbutton, so i need my pushbutton invisible on my figure window.
My script:
% --- 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)
[s,fs]=wavread('filename.wav');
sound(s,fs);
Thankyou..
To make your push button invisible when you click it, set visibleto off in the callback function
set(hObject, 'Visible', 'off')
To make it invisible from other parts/functions in your GUI, just replace hObject with the handle of your push button.
Update:
You could make a clickable image and play different sounds for different click positions. Use the callback 'ButtonDownFcn' to trigger at a click event in the image. You can the retrive the position of the click by using the axes property 'CurrentPoint'. This return as 2x3 matrix with x-y-z projected coordinates. But as you are using a 2D plot you could simply pick the first 2 values, read more here.
Then use the x/y coordinates to find out what in the image that the user clicked on and play the sound for that.
A simple example:
% Draw an image
figure()
imHandle = image(imread(figPath));
% Set callback function (target function could have any name)
set(imHandle,'ButtonDownFcn', #ImgClickCB);
And the callback function (displays the x and y coord.)
function ImgClickCB(hObject, ~)
clickPoint = get( get(hObject,'Parent'), 'CurrentPoint');
fprintf('Clicked at x: %0.f y: %0.f \n', clickPoint(1,1), clickPoint(1,2));
The following example hides, and shows a pushbutton.
I created a sample, without using guide.
You can copy and paste the code into Matlab m file for execution.
Creating GUI without guide tool, better suit Stack Overflow site, because there is no need to attach a fig file.
You better use guide tool, because creating a GUI without it is complicated.
The following code sample hide (and show) pushbutton:
%TestNoGuideHideButton.m
%Create GUI with two buttons, without using GUIDE.
function TestNoGuideHideButton()
%Create figure.
h.fig = figure('position', [800 400 260 80]);
%Add button, with callback function Button1
h.buttonOne = uicontrol('style', 'pushbutton',...
'position',[10 20 100 40], ...
'string' , 'Button1', ...
'callback', {#Button1});
%Add button, with callback function hideButton
h.buttonTwo = uicontrol('style', 'pushbutton', ...
'position',[150 20 100 40], ...
'string' , 'Hide Button1', ...
'callback', {#hideButton});
function Button1(hObject, eventdata)
%Modify color of Button1 to random color.
set(h.buttonOne, 'BackgroundColor', rand(1, 3));
end
function hideButton(hObject, eventdata)
is_visible = isequal(get(h.buttonOne, 'Visible'), 'on');
if (is_visible)
%Hide buttonOne if Visible.
set(h.buttonOne, 'Visible', 'off');
set(h.buttonTwo, 'string', 'Show Button1'); %Replace string.
else
%Restore buttonOne if hidden.
set(h.buttonOne, 'Visible', 'on');
set(h.buttonTwo, 'string', 'Hide Button1'); %Replace string.
end
end
end
For the problem you described above, you obviously can't add a button for showing and hiding the other button.
You can restore the button when playing finishes.
You can also add a callback function for the background figure (look for WindowButtonDownFcn in guide).
Pressing anywhere on the figure, triggers the callback, were you can restore the hidden button.
You might want to have a look at this blog entry where I discussed how to manipulate the CData property of uicontrols.
I've added some code below to show a simple example:
f = figure(); % create a figure with an axes on it
pb = uicontrol('Style','checkbox', 'Units','pixels', 'Position',[10 10 300 200], ...
'Callback',#(a,b)msgbox('play clown!'));
% read some data
data = load ( 'clown' );
% extract out the image
img = data.X;
% convert image to RGB for displaying on checkbox
img = ind2rgb(img,colormap(f));
% Set the cdata property of the checkbox to be the image of interest
set(pb, 'CData', img )
The above code creates a figure with an image of a clown which you can click on (this could be your drum). The "button" stays there the whole time you don't need to make it invisible
Note: I use a checkbox instead of a button -> because sometimes a button can have a "border" when its in focus which can detract from the image whereas a checkbox doesn't.
I've copied the image produced below (after I clicked on the button):
excuse my noobness, but this is my first post.
i generated this gui in matlab, and i want to plot an image on one of the axis from an update function.
i know in Matlab you can just do something like
image(img)
hold on
plot(x1,z1)
hold off
but how can one do this with the gui?
here is a segment of the update function
%get a handle to the GUI's 'current state' window
deflectionx = findobj('Tag','deflectionx_display');
deflectiony = findobj('Tag','deflectiony_display');
depth = findobj('Tag','depth_display');
Graph = findobj('Tag','Graphical_display');
UltraS = findobj('Tag','UltraS_image');
%update the gui
set(deflectionx,'String',x_def);
set(deflectiony,'String',y_def);
set(depth,'String',insert_depth);
%% above works fine. below does not
%i want this to plot those points on top of the image in the large graph panel of the gui
plot(Graph,img1)
hold on
plot(Graph,x1,z1);
hold off
%this should plot the second image on the UltraS panel
plot(UltraS,img2)
Please and thanks in advance!
So figured it i had to write the handles of the GUI to the workspace in the opening function of the gui
% --- Executes just before VR_gui is made visible.
function VR_gui_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 VR_gui (see VARARGIN)
% Choose default command line output for VR_gui
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
%setting axis
needle_plot = handles.Graphical_display;
US_plot = handles.US_image;
%write handle to workspace
assignin ('base','needle_plot',needle_plot);
assignin ('base','US_plot',US_plot);
then read the workspace variables from the update function
needle_plot = evalin('base','needle_plot');
US_plot = evalin('base','US_plot');
axes(US_plot);
image(img2);
axes(needle_plot);
plot(x1,z1,'r--o');
After loading an image into a Matlab GUI, how can I pass that image using pushbutton to another Matlab file? When I push the button in my GUI, the image should be passed to my Matlab code.
Here is my GUI code
% --- 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)
[filename,pathname]=uigetfile(...
{'*.jpg;*.gif;*.png;*.bmp',...
'image file(*.jpg,*.gif,*.png,*.bmp)';'*.*','all files(*.*)'},...
'open the image file to be verified');
fullimagefilename = fullfile(pathname,filename);
axes1 = imread(fullimagefilename);
axes(handles.axes1);
image(axes1);
%axes(handles.axes1);
%imshow('E:\degraded images\3.jpg')
% --- 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)
-pushbutton 1 is used to browse file .
-and by pushbutton2 i want to pass the browsed file to my base file and its code is
im=imread('E:\degraded images\3.jpg');
hsv = rgb2hsv(im);
hueImage = hsv(:,:, 1);
meanHue = mean2(hueImage);
figure, imshow(im);
title(meanHue);
%figure , imshow(im);
%im = imresize(im, 0.5);
%im2 = imread('E:\degraded images\3.jpg') ;
im2= im;
im=im(:,:,1);
sigmaA=8;
sigmaB=10;
sigmaMax=max([sigmaA sigmaB]);
fsz=[sigmaMax, sigmaMax];
If I understand correctly, the GUI uses pushbutton1 to allow the user to choose a file and display it in the axes. When the user presses the other button, pushbutton2, which is presumably on the same GUI, you want the callback for that button to have access to the selected (or browsed) image.
This can be done by creating a field in the handles structure for the selected image data, then storing this data using the guidata function.
In your first callback, do something like the following
function pushbutton1_Callback(hObject, eventdata, handles)
[filename,pathname]=uigetfile(...
{'*.jpg;*.gif;*.png;*.bmp',...
'image file(*.jpg,*.gif,*.png,*.bmp)';'*.*','all files(*.*)'},...
'open the image file to be verified');
% need to handle the case where the user presses cancel
if filename~=0
fullimagefilename = fullfile(pathname,filename);
% create an img field in handles for the image that is being loaded
handles.img = imread(fullimagefilename);
axes(handles.axes1);
image(handles.img);
% save the application data
guidata(hObject,handles);
end
Now in your second callback, you can access this file through the handles struct
function pushbutton2_Callback(hObject, eventdata, handles)
% check to ensure that img exists in handles
if isfield(handles,'img')
% copy the image from the handles structure
im=handles.img;
% continue with your code
hsv = rgb2hsv(im);
% etc.
end
And that is it - the first callback saves the image to the handles structure as a field within it, and the second callback retrieves that image from handles via the img field.
Try it out and see what happens!
When I try to invoke a subfunction in a GUI/GUIDE file (using a function handle which has been exposed as a global variable), a new axes is always created even if I set the axes to a specific axes in the GUIDE figure. Does anyone know why this is happening? GUIDE code is:
###############################################################
function varargout = demo(varargin)
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', #demo_OpeningFcn, ...
'gui_OutputFcn', #demo_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
function demo_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
global myhandles updateFunction;
myhandles = handles;
updateFunction = #update;
function varargout = demo_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
function pushbutton1_Callback(hObject, eventdata, handles)
update();
function update()
global myhandles;
axes(myhandles.axes1);
plot(1:2,1:2);
###########################################################################
And when I do (outside file above):
global updateFunction;
feval(updateFunction)
I always see the plot in a newly created figure window, not in the GUI figure. Why is this happening?
The first thing I would try is to replace the function update with the following:
function update
global myhandles;
plot(myhandles.axes1,1:2,1:2);
This will explicitly tell the PLOT function to plot into the given axes. If that doesn't work, try setting the axes 'NextPlot' property to 'add' (probably in demo_OpeningFcn):
set(myhandles.axes1,'NextPlot','add');
By default, when you create a GUI using GUIDE, Matlab sets the 'HandleVisibility' property of all objects associated with the GUI to 'callback'. This means that you cannot set these handles to be the current figure or current axis from anywhere outside of the callback routines (ie. from the command line or an external function).
To work around this you can either specify the appropriate handle explicitly in all of your plotting functions or you can set the 'HandleVisibility' property of the axes to 'on'. This can be done on an object by object basis via the property inspector, or for the entire GUI by going to 'Tools -> GUI Options...' and changing the 'Command-line Accessibility:' to 'on'.