Particle Detection In script but not in App Designer Function

조회 수: 1 (최근 30일)
Brett
Brett 2023년 10월 19일
댓글: Cris LaPierre 2023년 10월 21일
I have an existing script that I am attempting to turn into an app so that parameters of the program can easily be edited by the user. I have tried the methods to directly convert a script into a function for use in an app. The function runs, except it does not work the same way as a standalone script. The script I can tell is counting particles because there are symbols placed over the particles that it sees. In the app, no such symbols appear. Is this due to my conversion from script to function, app designer, or something else? Thank you.
function [spot_past, t, tmin] = tirf_analyzer_chalmers(app)
dt = str2double(app.dtEditField.Value);
tmin = str2double(app.tminEditField.Value);
istart = str2double(app.istartEditField.Value);
iend = str2double( app.iendEditField.Value);
th_high = str2double(app.th_highEditField.Value);
th_medium = str2double(app.th_mediumEditField.Value);
th_low = str2double(app.th_lowEditField.Value);
spot_rad = str2double(app.spot_radEditField.Value);
rem_size = double(app.rem_sizeEditField.Value);
default_dir='C:\Users\bab322\OneDrive-Lehigh University\Documents\School\Grad school\Wittenberg';
[FileName,PathName] = uigetfile('*.tif','Select the image-file',default_dir);
if FileName==0
return
end
file_in=strcat(PathName,FileName);
spot_past=[];
% spot_past contains information from all binding events. spot_present only
% contains info about the spots that are currently visible (more than rem_size
% connected pixels with intensity > th_high).
spot_present=[];
N_frames=iend-istart+1; % Number of frames to analyze.
t=(0:1:N_frames-1)*dt; % Real time points for all frames.
% Go through each frame.
for i=1:N_frames
I=double(imread(file_in,istart+i-1)); %I is a matrix with all pixel values.
% Compare all pixel values with the higher threshold.
% A logical matrix is created.
spots_logical = I>th_high;
% Subtract the average pixel value of the area not covered by spots
% from all pixels. i.e. background intensity subtraction. Note that
% this is done for every frame independently.
I=I-mean(I(~spots_logical));
% Convolution with at gaussian profile performs a lowpass filtering
% of the image. This is to average out rapid changes in the intensity.
h=fspecial('gaussian',[3 3],1);
I=imfilter(I,h,'replicate','conv');
spots_logical=bwareaopen(spots_logical,rem_size); % Removes spots with area less than rem_size pixels.
L=bwlabel(spots_logical); % Finds and labels the connected pixels (spots), with intensity > th_high
% Acquires the centroid position of each spot; centroids is
% a Nx2-matrix where centroids(:,1) is the x-positions and
% centroids(:,2) the y-positions.
s=regionprops(L,'Centroid');
centroids=cat(1,s.Centroid);
% 160127: Add new vesicles, update position, maximum intensity and maximum total intensity. First it
% loops through all spots in the current image
for j=1:size(centroids,1)
% Takes the difference in position between the position of the
% current spot and all spots stored in the spot_past. If the
% distance is >= than spot_rad to all other spots we have a new
% spot.
if isempty(spot_present)
dist=[];
else
dist=sqrt((centroids(j,1)-spot_present(:,4)).^2+(centroids(j,2)-spot_present(:,5)).^2);
end
if any(dist<spot_rad)
% We have found a spot that is already bound to the surface.
% Updates its centroid position (in case it has moved slightly)
% and checks if the pixel value at the centroid position has
% increased (then update that too). Indicate that it still has
% an intensity > th_medium.
pos=find(dist==min(dist(dist<spot_rad)));
% If two spots are equally close. Just pick the one with lowest index.
if length(pos)>1
pos=min(pos);
end
if ~isempty(pos) % If more than one spot is close, then the closer is chosen.
spot_present(pos,:)=[spot_present(pos,1),t(i),t(i),centroids(j,1),centroids(j,2),...
max([I(round(centroids(j,2)),round(centroids(j,1)));spot_present(pos,6)]),...
max([sum(sum((L==j).*I));spot_present(pos,7)])];
end
else
% A new spot! Update the spot past with the new values.
spot_present=[spot_present;[t(i),t(i),t(i),centroids(j,1),centroids(j,2),I(round(centroids(j,2)),round(centroids(j,1))),sum(sum((L==j).*I))]];
end
end
%spot_past
%spot_present
% Check and update status of the spots bound at the previous time point
% (if any). Look at the current pixel value at the currently reported
% centroid position (rounded to a certain pixel).
if ~isempty(spot_present) % This is true if spot_present contains values.
% Int will here contain the current pixel values at each current
% centroid position (rounded).
Int=I(round(spot_present(:,5)),round(spot_present(:,4)));
% Int is a 2D matrix containing all the pixel values for x1 and y1
% ...yn in the first row and xn and y1 ... yn in the last row. The
% diagonal elements correspond to (x1,y1) ,(x2,y2) ... (xn,yn); the
% values that we are interested in.
% Put the pixel values at each current centroid position (rounded)
% from the diagonal of the square matrix Int, in a vector Int.
Int=diag(Int);
% Update the second column in spot_present (last time with pixel
% value > th_medium) for all spots with pixel value >= th_medium.
% The spots that are not bright enough will not have the time updated.
spot_present(Int>=th_medium,2)=t(i); % Still bound, intensity > th_medium.
% Update the third column in spot_present (last time with pixel value above
% th_low) for all spots with pixel value >= th_low. The
% spots that are not bright enough will not have the time updated.
spot_present(Int>=th_low,3)=t(i); % Still bound, intensity > th_low.
% Updates spot_past with the spots that has bleached, detached or
% fused with the surface and removes them from spot_present.
spot_past=[spot_past;spot_present(Int<th_medium,:)];
spot_present=spot_present(Int>=th_medium,:);
end
% Shows the current image with the identified spots with
% a cross over their respective centroid position.
disp(['done = ',num2str(i),':',num2str(N_frames)])
%read image
Is=imread(file_in,istart+i-1);
Is=Is-mean(Is(:)); % OW: Maybe the other alternative is better.
figure(1), imshow(Is,[0,400])
title(sprintf(['Frame number: ',num2str(istart+i-1)]))
hold on
if ~isempty(spot_present) % This is true if spot_present contains info.
% t_bound is a column vector stating the time present spots have
% been bound to the surface so far.
t_bound_present=spot_present(:,3)-spot_present(:,1);
% If the time bound (t_bound) is shorter than (or equal to) tmin AND the spot
% attached before(/or in) in the current frame it is considered
% as loosely attached and is put in the spots_loose_present matrix (yellow crosses).
% Also note that spots that are dim at the centroid position
% will end up in the spot_loose_present matrix.
spots_loose_present=spot_present(t_bound_present<=t(tmin) & spot_present(:,1)<=t(i),:);
% If the time bound (t_bound) is longer than tmin AND the spot
% attached before(/or in) in the current frame it is considered
% as firmly attached and is put in the spots_firm_present matrix (blue crosses).
spots_firm_present=spot_present(t_bound_present>t(tmin) & spot_present(:,1)<=t(i),:);
% Detected spots that have been attached to the surface shorter than tmin
% (loosely attached) are marked with yellow crosses.
% Detected spots that have been attached to the surface longer than tmin
% (firmly attached) are marked with blue crosses.
plot(spots_loose_present(:,4),spots_loose_present(:,5),'y+')
plot(spots_firm_present(:,4),spots_firm_present(:,5),'b+')
end
if ~isempty(spot_past) % This is true if spot_past contains info.
% t_bound_past is a column vector stating the time past spots stayed
% above the th_low intensity level.
t_bound_past=spot_past(:,3)-spot_past(:,1);
% t_off is a column vector stating the time past spots stayed
% above the th_medium intensity level.
t_off=spot_past(:,2)-spot_past(:,1);
% Find the loosely attached spots that have detached.
% The time above th_medium has to be smaller than tmin AND
% detection time plus time above th_medium has to be one dt
% shorter than the current time-point.
spots_off_loose=spot_past(t_off<t(tmin+1) & (spot_past(:,1)+t_off)==t(i-1),:);
% Find the firmly attached spots that have detached.
% The time above th_medium has to be greater than or equal to tmin AND
% detection time plus time above th_medium has to be one dt
% shorter than the current time-point.
spots_off_firm=spot_past(t_off>=t(tmin+1) & (spot_past(:,1)+t_off)==t(i-1),:);
% Loosely attached spots that just detached are marked with yellow rings.
plot(spots_off_loose(:,4),spots_off_loose(:,5),'yo','LineWidth',2)
% Firmly attached spots that just detached are marked with blue rings.
plot(spots_off_firm(:,4),spots_off_firm(:,5),'bo','LineWidth',2)
% Find the firmly attached spots that have bleached.
% The time above th_medium has to be greater than or equal to tmin AND
% detection time plus time above th_medium has to be one dt
% shorter than the current time-point AND time above th_medium must
% be different from time above th_low.
spots_off_bleach=spot_past(t_off>=t(tmin+1) & (spot_past(:,1)+t_off)==t(i-1) & t_off~=t_bound_past,:);
% Firmly attached spots that bleached are marked with red rings.
plot(spots_off_bleach(:,4),spots_off_bleach(:,5),'ro','LineWidth',2)
end
hold off
drawnow
pause(0.5)
end
% Finally, update spot_past with the last data in spot_present that haven't
% lost contact with the surface.
spot_past=[spot_past;spot_present];
dt=.5, tmin=3, istart=1, th_high =15000, th_medium=7500, th_low=3500, spot_rad=10, rem_size=4, iend=length(imfinfo(file_in))

채택된 답변

Cris LaPierre
Cris LaPierre 2023년 10월 19일
Assuming your app is displaying the image in axes in the app canvas and not in a separate figure window, then I think the issue is that, when plotting in an app, you must specify which axes to plot to. Same with hold. Try updating your plot commands to use this syntax:
Taking one of your plotting commands, it might look something like this. Use the Component Browser in app designer to find the component name of your axes.
hold(app.UIAxes,'on')
plot(app.UIAxes,spots_loose_present(:,4),spots_loose_present(:,5),'y+')
hold(app.UIAxes,'off')
  댓글 수: 15
Brett
Brett 2023년 10월 20일
This version provides the below error.
[app.filename,pathname] = uigetfile('*.tif','Select the File to Open');
app.fullname = [pathname,app.filename];
app.selected_File=tiffreadVolume(app.fullname);
info=imfinfo(app.fullname);
app.File_location=pathname;
[path, app.name, ext]=fileparts(app.filename);
app.iend=length(info);
% The part that saves the plotting data into excel--------------
data = table(t', nbr_spots_firm','VariableName', {'Time (s)', 'NboundSpots'});
writetable(data, fullfile(app.File_location, app.name, "TimevsBoundSpotsFig1.xlsx"));
Error using EFA_final/StartButtonPushed
Unable to save the workbook to file 'C:\Users\bab322\OneDrive - Lehigh University\Documents\School\Grad
school\Wittenberg\EFA Analysis\test files\File1_more spots\File1_more spots\TimevsBoundSpotsFig1.xlsx'.
Check that write permissions are available, there is sufficient disk space, and the file can be written
to or created.
I also tried it a few other ways of naming and arranging the properties. Including defining
[path, name, ext]=fileparts(app.filename)
in the callback of the function and then writing the saving function as seen here.
writetable(data, fullfile(app.File_location, name,"ResidenceTimesFig3.xlsx"))
While it would have been nice, all the variations I have tried result in nothing being saved at all, or the above error message being displayed. The user can just ensure the file is in a folder of its own so that the excel files will not be mixed up. Thank you again.
Cris LaPierre
Cris LaPierre 2023년 10월 21일
Final thought, then, is to make sure the Excel sheet you want to write to is closed. See here: https://www.mathworks.com/matlabcentral/answers/514294-why-does-readtable-fail-to-read-a-file-from-onedrive

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Develop Apps Using App Designer에 대해 자세히 알아보기

제품


릴리스

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by