Problems with displaying edited pictures in a GUI created in MATLAB - matlab

I have an assignment to create a GUI using MATLAB GUIDE and am having a problem with displaying an edited picture. I need to have buttons that edit the picture (eg. remove red, blue, green components and rotate) and display that edited picture. I am using imshow to display the edited picture but it displays in a new window and shuts down the GUI I had running. Can anyone help?
I've been working on this and have tried numerous different ways of fixing the problem but none worked. However, I am using MATLAB 7.0.1, and 7.7.0 might have an update for this problem.

When you first plot the image with imshow, have it return a handle to the image object it creates:
A = (the initial matrix of image data);
hImage = imshow(A);
Then, to update the image with new data, try the following instead of calling imshow again:
B = (modification of the original image matrix A);
set(hImage, 'CData', B);
Using the set command will change the image object you already created (a list of image object properties can be found here).
Alternatively, you can also add additional parameters to a call to imshow to tell it which axes object to plot the image in:
hAxes = (the handle to an axes object);
imshow(A, 'Parent', hAxes);
EDIT:
Addressing your additional problem of sharing GUI data between functions, you should check out the MATLAB documentation here. As noted there, there are a few different ways to pass data between different functions involved in a GUI: nesting functions (mentioned on SO here), using the 'UserData' property of objects (mentioned on SO here), or using the functions setappdata/getappdata or guidata. The guidata option may be best for use with GUIs made in GUIDE.

The GUI m file functions automatically assign the image data to a variable called hObject. Once you have done your image alteration, you have to reassign the new data to hObject:
hObject = imshow(newimagedata)
Don't forget to update and save this operation by:
guidata(hObject, handles)

Related

How to save plot with its colourbar as .fig in Matlab GUI

I have a button which will produce plot along with its color bar by clicking on it. The button relates to certain function called zzpcolor. Inside zzpcolor, I use pcolor syntax to produce shake map.
Inside the callback function, I use hold on to hold the figure generated by zzpcolor. Then I add another plot to the same axis. This is part of the script within the push botton callback.
axes(handles.axes1);
axes1.Position=[0.1300 0.1100 0.7750 0.8150];
[X,Y,Z]=plotpcolor(fnamedat);
hold on
zzpcolor(X,Y,Z);
shading flat
LimitPlot
hold on
plot_google_map
hold on
scatter(datageo(:,1),datageo(:,2),'MarkerFaceColor',[1 0 0])
hold off
The syntax worked just fine. I use this syntax to save the plot as jpg in another callback function.
newfig1 = figure('Visible','off');
copyobj(handles.axes1, newfig1);
[filename,pathname]= uiputfile('*.jpg','Save as');
hold on
wmmicolorbarsetting;
saveas(newfig1,[pathname,filename],'jpg');
it works just fine. But when I try to save it as .fig using similar syntax like this,
newfig1 = figure('Visible','off');
copyobj(handles.axes1, newfig1);
[filename,pathname]= uiputfile('*.fig','Save as');
hold on
wmmicolorbarsetting;
saveas(newfig1,[pathname,filename],'fig');
the .fig file contains nothing. Why?
The .fig file does contain something. You set the figure Visible property to 'off' so the figure doesn't actually show up when you create the figure or when you load the figure from the file.
You can verify this by loading the .fig file with hgload and setting the Visible property to 'on'.
fig = hgload([pathname, filename]);
set(fig, 'Visible', 'on')
You can also look at the produced .fig file and ensure that it is non-empty.
You can fix this by setting Visible to 'on' prior to saving.
A note on figure visibility: Setting Visible to 'off' is useful for saving a figure as a format other than .fig (png, jpeg, etc.) because you can create an image without worrying about a bunch of figures showing up as your script runs. In these cases, no user interaction is required. As you've found out, if you actually need to see/interact with figures, Visible should be 'on' to be useful.

Activate a specific figure when returning from a nested function

I have a plotting function inside imshow() command.
The plot and the image should be in separate figures.
At the return from the inside function the current figure is of the plot thus imshow() puts the image onto the same figure of the plot and kills the plot.
What can be done to make imshow() open or get to an existing its own figure, while keeping such manner of nested function calling?
Well, apparently, I've found an answer by the time I was done with the question, but because I find it interesting enough and find nothing answering it I'm writing the answer as well.
The algo is like this:
open a figure before imshow(nested_function());
upon starting the nested_function() save the handle to the
previous figure like fh_prev = gcf; for example
do any plots along the nested_function()
before return from the nested_function() activate the previous
figure with the command figure(fh_prev);

Matlab opens new figure in Callback despite hold

I am creating a GUI with MATLAB's GUIDE. Say, the GUI consists of an axis called axis1
and a slider called slider1. Further say I wanted to plot something (e.g. a box) into axis1 and change the box's height with the slider.
I tried doing this by adding a listener to the slider like so:
hListener = addlistener(handles.slider1,'Value','PostSet',#(src,evnt)boxHeightChange(src,evnt, handles.figure1));
in the GUI's opening function. I further defined:
function boxHeightChange(src, event, figname)
handles = guidata(figname);
% delete "old" box
delete(handles.plottedHandle);
% bring axis in focus
axes(handles.axes1);
% plot the new box (with changed size)
hold on; boxHandle = plotTheBox(event.AffectedObject.Value); hold off
handles.plottedHandle = boxHandle;
% update saved values
guidata(figname, handles);
end
This works, but always opens a new figure to plot the resizable box into instead of drawing into handles.axes1. I do not understand why, since I call axes(handles.axes1); and hold on;
Any idea that might explain the behavior?
I will post a solution to my own question.
Apparently the Callback of a listener is not declared as a "GUI Callback" which is why the GUI can not be accessed from within boxHeightChange if the GUI option "command-line accessibility" is not set to "On".
That means: In GUIDE go to Tools -> GUI options and set "Command-line accessibility" to "On".
Most plotting functions let you pass a name value pair 'Parent', ah where ah specifies the axes to plot on. I think this is the best way to handle your problem. Your actual plotting command seems to be wrapped in the plotTheBox function, so you will have to pass the axes handle in somehow.
Your plot command will look something like this:
plot(a,'Parent',handles.axes1)
You solved the problem a different way on your own, but I think you should do it my way because it's more explicit and it's less likely to lead to unforeseen problems.

Display "imshow" images in a GUI using GUIDE

I have a piece of code that is 300 lines long. There is 3 different instances of imshow throughout the code that displays figures as the code is run..
The GUI I am creating will be very simple. Currently I have a push button that initiates the m file.
I am trying to get the images to be displayed within the GUI that I am creating and not in separate Figure windows.
I have being looking at tutorials online but cant get a quick fix for my problem, they all get a bit convoluted and I cant figure out what exactly to do.
I have 3 axis inserted onto the GUI, In the "view callbacks" for each axis I can createfcn, deletefcn and buttonDownFcn. When I createFcn it gives me a hint to "place code in OpeningFcn to populate axes1" in the auto generated code.
I have tried to do this but I am not able to find the correct place to write the code.
Can somebody tell me if I am going in the correct direction or if I have it wrong.
Thanks
In order to display these images, you need to declare the parent in imshow. The parent is what you want to act as the canvas for your image, and in your case will be an axes.
I created a very simple gui with three axes and a push button. MATLAB named my axes axes1, axes2 and axes3. Guide saves the handles to these axes so that you can interact with them throughout your gui code. For example, you mentioned the opening function... here is mine with a call to imshow (the only lines I added were the last three ones):
% --- Executes just before myGUI is made visible.
function myGUI_OpeningFcn(hObject, eventdata, handles, varargin)
% Choose default command line output for myGUI
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes myGUI wait for user response (see UIRESUME)
% uiwait(handles.figure1);
imshow('myImage1.png', 'Parent', handles.axes1)
imshow('myImage2.png', 'Parent', handles.axes2)
imshow('myImage3.png', 'Parent', handles.axes3)
Notice that I can grab the handles of my axes and then declare them to be the parents for the results of my imshow call.
If you're not sure what the names of your handles are, you can check in the GUI editor by right clicking, looking at the property inspector, and the tag property.
If you want to perform a similar operation for when you click on your pushbutton, right click on the button in the editor, and click on View Callbacks -> Callback, and you can add your imshow code there.
Good luck.
If I understand correctly you just want your images to appear in the axes instead of a figure. Try setting the focus to the axes itself before showing the image.
axes(1);%you may need to change the one to your axes handle.
imagesc(imageToBeDisplayed);
axes(2);
imagesc(secondImage);
axes(3);
imagesc(thirdImage);
This way before you call imagesc you make sure your program knows where to send the image. Otherwise it may just create a figure.

The subplot function called in different matlab views

I have built a matlab application consisting of 2 views, each one knowing about the other's handle.
The main view launches the second view and gets its handle.
Then the function subplot() is called in the main view and an image is displayed using imshow().
What I would like to do is to display in the second view several details of the image, also by using the subplot() and imshow() functions.
Using the handle of the second view I call from the main view a function defined in the second view, which further calls subplot() and imshow() functions for details.
What happens is that initial image in the main view disappears being replaced with the details.
Can anybody give me an advice so that I can have the image displayed in the main view while the details are shown in the second view ?
Maybe you need to specify the axis in which you are placing your image or data. The imshow command allows you specify the axes to use for displaying images with the Parent parameter.
Combine this with the fact that subplot returns a handle to the axis it creates and you have.
h = subplot(m,n,i) %# create a subplot axes
imshow(img,'Parent',h) %# display an image in the previously created axis
Assuming you can pass information between the two sets of code you would need to retrieve the handle to the axis you want the image to show up in and use that handle in the call to imshow. Here is an example
hFig = figure;
h(1) = subplot(2,2,1)
h(2) = subplot(2,2,2)
setappdata(hFig,'axisHandles',h) %# stores the axes handles in appdata of the figure
....
Now when you want to show some an image in the first figure you can do the following assuming you know the handle to each of your figure windows.
h=getappdata(hFig,'axisHandles')
imshow(img,'Parent',h(1))