APP DESIGNER: Issue with using properties between callback functions.

Hi,
I am working on an image segmentation GUI. When I load in my volume, I am storing it in a property I made called "app.volume". I do this as I want to use the volume between callback functions. I load in my volume in one callback function and assign app.volume the data. However, when I move onto the following callback function, in which I need to use the app.volume data, I am not able to retrieve it.
I am not sure why this is happening, and I need to be able to work with the volume between various callback functions. Any advice?

17 Commenti

Can you post the code for the two callbacks?
% Button pushed function: SelectDICOMDirectoryButton
function SelectDICOMDirectoryButtonPushed(app, event)
% User will select the DICOM directory of choice
clc; clearvars; close all; % to clear anything that may have previously been loaded
% to open windows directory, to find the image to be segmented
desktop=winqueryreg('HKEY_CURRENT_USER', 'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', 'Desktop');
desktop=strcat(desktop,'C:\Users\anupr\MATLAB Drive\capstone\saggitalSpinalCT');
[PathName] = uigetdir(desktop);
f = waitbar(0,'Loading DICOM Directory');
pause(0.5)
waitbar(.15,f,'Loading DICOM Directory');
pause(3)
% How many images are in the directory?
a=dir([PathName '/*.dcm']);
out=size(a,1);
waitbar(.33,f,'Loading DICOM Directory');
pause(2)
waitbar(.50,f,'Loading DICOM Directory');
pause(3)
% read in the images
name = extractfield(a,'name')';
waitbar(.67,f,'Loading DICOM Directory');
pause(2)
for i=1:out
holder = char(name(i));
myFile = strcat(PathName,'\',holder);
img(:,:,i)=dicomread(myFile);
metadata(i) = dicominfo(myFile);
end
waitbar(.85,f,'Loading DICOM Directory');
pause(2)
waitbar(1,f,'Loading DICOM Directory');
pause(0.1)
close(f)
clear f;
app.volume = img;
disp(size(app.volume))
app.metadata_vol = metadata;
end
% Button pushed function: ViewDICOMSeriesButton
function ViewDICOMSeriesButtonPushed(app, event)
disp(size(app.volume))
sliceViewer(app.volume);
end
What do you mean you are not able to retrieve it? Is there an error message? if so, please share the complete error message (all the red text).
Hi Rik,
I have posted the code above. Note that the "disp(size(app.volume))" were lines that I added for debugging to confirm that the app.volume was not being carried over to the other callback functions. In the "SelectDICOMDirectoryButtonPushed" function, the size is outputted as 512 513 512, and in the "ViewDICOMSeriesButtonPushed" function, the size is 0 0.
My properties are defined as follows:
properties (Access = private)
anatomy % stores the anatomy, to be used in the logic of the segmentation algorithm portion
volume % holds the original DICOM volume
startSlice % Value of starting Slice #
endSlice % Value of ending Slice Number
BW_volume % Binary Mask for Volume
metadata_vol % metadata of the DICOMs for total volume
end
Hi Cris,
Please see below for the screenshot of the error. As you can see, because sliceViewer requires an MxNxP volume, it throws an error. I verified that in the "SelectDICOMDirectoryButtonPushed", my debug line, disp(size(app.volume)), output is 512 513 512, which is a MxNxP matrix. However, when I check for the app.volume size in "ViewDICOMSeriesButtonPushed", the debug line output is 0 0. This shows that my data assigned to app.volume in the original callback function is lost when I am trying to use it in the second callback function.
What do you do between pressing SelectDICOMDirectoryButtonPushed and ViewDICOMSeriesButtonPushed?
Hi Cris,
Nothing at all, the user should click the button to first load the DICOMs and then click the View DICOM button to view the series. There is nothing that happens between those two steps / callback functions.
Is your app object actually named "app"? Sometimes I see people change the app object name and then copy-paste solutions into their app without adapting the object name. Although, on second thought, you'd probably get an error that "app" is an unknown function or variable in that case.
If the folder in PathName did not contain any dcm files, 'a' would be an empty structure which would likely throw an error in extractfield() and 'out' would be 0 so "img" would never be defined which would also throw an error whem img is assigned to app.volume. So that eliminates the possibility that no dcm files were found.
I see that you are not preallocating the img and metadata variables. I wonder if your dicom images are being read successfully.
Hi Adam,
The images are read successfuly in the first callback function. I have tested for this scenario. So that is not the issue.
Have you tried placing a break point at the end of SelectDICOMDirectoryButtonPushed() and then running the code to that point, and manually executing disp(size(app.volume))? Knowing the outcome of that would eliminate some possibilities.
Are there any other warnings or errors when you open the app or when using any other features of the app?
Hi Adam,
I have tried your suggestion of placing a breakpoint at the end of the SelectDICOMDirectoryButtonPushed() callback function. Please see the image below for the placement of the breakpoint.
After it breaks, I ran the disp(size(app.volume)) in the command window and this was my output.
This is odd - I don't clear the variable, so I am not sure why this is happening. Also I am not sure why this happens in this point of the code, since before I added the breakpoint, and disp(size(app.volume)) was directly run in the callback function, it displayed the expected output (512 513 512).
I think I have discovered the issue. In the SelectDICOMDirectoryButtonPushed() callback function, I have the following line at the beginning of the function:
clc; clearvars; close all; % to clear anything that may have previously been loaded
I added this line so that if a user chose the incorrect folder, it would clear everything and start again. When I commented out this line, I was able to view the slices in the next callback function.
I am confused as to why this happens though; this LOC is run way before my assignment line to app.volume. Why is app.volume affected by this?
Ah, I missed that. That clears your app object from the function workspace so when you assign data to app.volume, "app" becomes a structure variable which is cleared when the SelectDICOMDirectoryButtonPushed function ends. The "app" object still exists outside of the function but its values are gone which is why it retains the [0,0] size in the next callback function.
Lesson learned: there is rarely a need to clear variables within function workspaces. One exception is if a variable size is large and you no longer need it and want to reduce memory.
Hi Adam,
Yes that makes a lot of sense. Thank you so much for your help.

Accedi per commentare.

 Risposta accettata

Cris LaPierre
Cris LaPierre il 10 Feb 2022
Modificato: Cris LaPierre il 10 Feb 2022
I think I have discovered the issue. In the SelectDICOMDirectoryButtonPushed() callback function, I have the following line at the beginning of the function:
clc; clearvars; close all; % to clear anything that may have previously been loaded
Ah, that's it.
That code clears the input variable app from the function workspace, so when you assign img to app.volume, you do so to a local variable, not the app property. Once the callback function finishes executing, that local variable is deleted. When you then call ViewDICOMSeriesButtonPushed, it passes in app without the volume property being populated.
You are in a function, so it is completely unnecessary to use any of that code. Your function starts with a brand new workspace with just the input variables. You do not need to clear, close, or clc anything.

Più risposte (0)

Categorie

Prodotti

Release

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by