Particle Detection In script but not in App Designer Function
1 view (last 30 days)
Show older comments
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))
0 Comments
Accepted Answer
Cris LaPierre
on 19 Oct 2023
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 Comments
Cris LaPierre
on 21 Oct 2023
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
More Answers (0)
See Also
Categories
Find more on Develop Apps Using App Designer in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!