I'm creating a GUI with a bunch of call back functions, the idea is to load an image an do a series of image transformation to it, I would like to keep those changes to the image and pass it around from one call back function to the other, I looked around to see if there is a similar case, even though there was plenty I couldn't figure out what's wrong with my code.
if true
% 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)
guidata(hObject, handles);
img = get(handles.edit1,'String');
I = imread(img);
guidata(handles.figure1,I);
imshow(I);
disp(handles.figure1);
% --- Executes on button press in pushbutton2. function pushbutton2_Callback(hObject, eventdata, handles) guidata(hObject, handles); h =findobj(0,'tag','figure1'); imshow(h); end

1 commentaire

Stephen23
Stephen23 le 10 Oct 2018
Modifié(e) : Stephen23 le 10 Oct 2018
This first line of code inside the callback serves no purpose:
guidata(hObject, handles);
handles is supplied by GUIDE as the third input argument to your function. There is absolutely no point in saving it straight away, without having made any changes or addition to it. Totally pointless.

Connectez-vous pour commenter.

 Réponse acceptée

Stephen23
Stephen23 le 10 Oct 2018
Modifié(e) : Stephen23 le 10 Oct 2018

0 votes

When you save I using guidata you replace the handles structure with I, and so handles does not exist any more (and hence none of its values or graphics handles exist either). Instead of throwing handles away, you should store your data as a field of the handles structure:
handles.I = imread(img);
guidata(hObject,handles);
This is exactly what all of the guidata examples show, which is why you should read the documentation.

6 commentaires

Mohamed Amine Henchir
Mohamed Amine Henchir le 10 Oct 2018
one last thing how would you call it in another callback function? I read the documentation but I couldn't quite get it, for example in the answer you provided, what is the difference between "handles.figure1" and "handles.I" I want to save the picture shouldn't just be "guidata(handles.I,handles)" thank you!
Stephen23
Stephen23 le 10 Oct 2018
Modifié(e) : Stephen23 le 10 Oct 2018
" what is the difference between "handles.figure1" and "handles.I""
handles.figure1 is the handle to some graphics object (defined by GUIDE).
handles.I is a numeric array (defined by your code). There is nothing interesting about it apart from that it contains some data that you want to process in various callbacks.
guidata is just a convenience wrapper that stores data in a figure's UserData. To make it more convenient to use, guidata uses its first input argument to find the parent figure. So the first argument to guidata must be some graphics object, but it really does not matter which one. Because the first callback argument is the handle of the graphics object that called that callback, that is the object that is most commonly used (like my answer shows).
"I want to save the picture shouldn't just be guidata(handles.I,handles)"
No. Read the guidata documentation. The syntax is shown like this:
guidata(object_handle,data)
Is handles.I an object handle? No it is not (it is a simple numeric array of data that you have imported). Then keep reading, to where it describes " guidata(object_handle,data) stores the variable data with the object specified by object_handle. If object_handle is not a figure, then the object's parent figure is used." Note that handles.I is not a graphics object, it is a simple numeric array, so it does not have a parent figure, so it cannot be used for the first argument.
You can think of the first input argument as being a kind of key to tell guidata where to store the second input argument. As the documentation clearly states, the second argument " data can be any MATLAB® variable, but is typically a structure, which enables you to add new fields as required." Basically you can just add new fields to handles and your data will be available wherever handles is accessible from. If you totally replace handles (like you were doing) then clearly you discard all of its contents (all graphics objects and data) , so GUIDE no longer can access them. That is why you can add field, but not remove them.
handles is just a structure.
You should learn about graphics objects:
Thank you so much for this detailed answer!I should probably put this in another question but it's also kind of related. so I'm using imcontrast to change the image contrast the problem is that the changes that I make don't get saved even though I click on adjust data button, the changes are saved if I do other manipulation like changing the size of the image, here is my code for the callback function:
if true
function pushbutton2_Callback(hObject, eventdata, handles)
handles = guidata(hObject);
guidata(hObject,handles);
axes(handles.axes1);
imshow(handles.I);
imcontrast(handles.figure1);
guidata(handles.figure1,handles);
end
Stephen23
Stephen23 le 10 Oct 2018
Note that imcontrast adjusts the image data within a graphics object (an Image). If you want to get the adjusted image data in an array then you will need to get it out of the image, something like this:
I = get(imh,'CData')
You might want to pause your GUI while that dialog box is open using waitfor.
function pushbutton2_Callback(hObject, eventdata, handles)
axes(handles.axes1);
imshow(handles.I);
h = imcontrast(handles.figure1);
waitfor(h)
guidata(hObject,handles);
end
I removed the unused guidata calls from your function, because GUIDE automatically provides handles as the third input argument to all callback functions.
I presume that you have read the imcontrast help and are aware of its limitation to grayscale images only, etc.
I get this error when I use I = get(imh,'CData'): Error using matlab.ui.Figure/get Invalid or deleted object.
Error in get_circles>pushbutton2_Callback (line 189) I = get(h,'CData');
here is my code for the callback:
if true
function pushbutton2_Callback(hObject, eventdata, handles)
axes(handles.axes1);
imshow(handles.I);
h = imcontrast(handles.figure1);
waitfor(h)
I = get(h,'CData');
handles.I = I;
imshow(handles.I);
guidata(handles.figure1,handles);
guidata(hObject,handles);
end
the Idea was to get the image from the h handle and store it where the original image is to overwrite it.
and thank you so much for all the insights!
Stephen23
Stephen23 le 11 Oct 2018
Modifié(e) : Stephen23 le 12 Oct 2018
This will not work:
h = imcontrast(handles.figure1);
The first input to imcontrast is described in its help as "...the image specified by the handle h". You are giving it the handle to some figure object. A figure object is not an image object. You need to provide it with a handle to the image object, just like the help explains.
This will not work:
waitfor(h)
I = get(h,'CData');
When you read the waitfor help it states that it "...blocks statements from executing until the MATLAB® object closes (is deleted)". So the code will continue once the imcontrast dialog box is closed. But once an object has been deleted you cannot get any properties from it, so you cannot expect to get anything out of an object that no longer exists. Note that a figure object does not have the property 'CData', so this would never work anyway: you need to give it the handle to the image.
Summary: Provide the image handle to imcontrast, as its help requires. To get the image data from the image replace the h with the image handle which is returned by imshow.
imh = imshow(handles.I);
dbh = imcontrast(imh);
waitfor(dbh)
I = get(imh,'CData');
Tip: you should read the documentation for every function that you use. I also recommend that you obtain and use the graphics handles for every graphics object that you need to refer to:

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Creating, Deleting, and Querying Graphics Objects dans Centre d'aide et File Exchange

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by