%%  Quick tracker algorithm.  Note that each ROI generates 6 total tracked quantities in the excel file 
% 1) Cross sectional area 
% 2) normalized cross sectional area, divided by the initial template 
% 3) Horizontal Distance of line through mean mask coordinate 
% 4) Vertical Distance of line through mean mask coordinate
% 5) Tangent line distance through horizontal mean-mask coordinate
% 6) Tangent line distance through vertical mean-mask coordinate
clear all
close all
clc


%% load tiff stack 
[filename_cell,pathname_cell] = uigetfile('*.*',  'All Files (*.*)','MultiSelect','on');
multi_image = iscell(filename_cell); 

% used to initialize if we load mulitple images at once. 
if multi_image == 0
num_images = 1; 
filename_cell_ = cell(1);
filename_cell_{1} = filename_cell; 
filename_cell = filename_cell_; 
end



%% Run through all images to find ROIs for automated alignment 
num_images = size(filename_cell,2)';
for nim = 1:num_images 
filename = filename_cell{nim};
pathname = pathname_cell;
im_info = imfinfo(sprintf('%s/%s',pathname,filename)); % return tiff structure, one element per image
nframes_ = size(im_info,1);
nframes(nim) = nframes_;
frame_val = input('Select Frame Index   ');

figure(1)
Mim = 0;
        for nf = 1:length(frame_val)
         im0 = imread(sprintf('%s/%s',pathname,filename), frame_val(nf)) ; % read in first image
         im0 = im2double(im0);         
Mim = Mim + im0/length(frame_val);
        end
im = Mim;
imagesc(im)
set(gca,'ydir','normal')
commandwindow;
apply_filter_ = input('Apply Filtering to Image (1 or 0)? ');


if apply_filter_ == 1 
figure(1)
cla
im = wiener2(im,[10,10]);
imagesc(im,[0,1])
set(gca,'ydir','normal')
end 
commandwindow;




load_roi = input('Load ROIs (1 or 0)?  ');


%% generate new rois 
if load_roi==0 

num_roi_ = input('Select Number of Regions of Interest  ');
num_roi(nim) = num_roi_;
appfilter(nim) = apply_filter_;

%% 
for j = 1:num_roi(nim)

% process ROIss     
ii = 1;
ntot = min(size(im,1),size(im,2));
im = im(1:ntot,1:ntot);
figure(1) 
subplot(1,2,1)
cla
imagesc(im), hold on 
set(gca,'ydir','normal')
rect = getrect;
xmin = rect(1,1); ymin = rect(1,2); 
width = rect(1,3); 
height = rect(1,4);
title('Select a Region to Track')
commandwindow;
deff{nim,j} = input('Is ROI deformable (1 or 0)?  ');

subplot(1,2,2)
cla
nx = round(xmin):1:round(xmin+width);
ny = round(ymin):1:round(ymin+height);
im_template = 0*im;
im_template = im(ny,nx);

imagesc(im_template), hold on 
set(gca,'ydir','normal')
title('Click to select bounding region, Press Ctrl + C to stop')



tdot = 0; 
p = []; 
while tdot == 0 
 [x,y] = ginput(1); 
 p = [p;[x,y]];
 plot(x,y,'r.','MarkerSize',10)
tdot = waitforbuttonpress;
end


p = round(p);
p = [p;p(1,:)];
[MX,MY] = meshgrid(1:size(im_template,2),1:size(im_template,1));
[mask,mask_contour] = inpolygon(MX,MY,p(:,1),p(:,2));
close(figure(1))
figure(1)
title('Select Box Area')
imagesc(mask)
set(gca,'ydir','normal')
rect = getrect;
xmin = rect(1,1); ymin = rect(1,2); 
width = rect(1,3); 
height = rect(1,4);
nax = round(xmin):1:round(xmin+width);
nay = round(ymin):1:round(ymin+height);
% nax(nax<min(nx))=[];
% nax(nax>max(nx))=[]; 
% nay(nay<min(ny))=[];
% nay(nay>max(ny))=[];
% 

area_mask = 0*im_template;
area_mask(nay,nax) = 1;

store_mask{nim,j} = mask;
store_area_mask{nim,j} = area_mask;
store_nx{nim,j} = nx;
store_ny{nim,j} = ny;
store_template{nim,j} = im_template;
close all
end


save_roi = input('Save ROIs (1 or 0)?  ');

if save_roi==1 
temp_mask{1,:} = store_mask{nim,:};
temp_store_area_mask{1,:} = store_area_mask{nim,:};
temp_store_nx{1,:} = store_nx{nim,:}; 
temp_store_ny{1,:} = store_ny{nim,:}; 
temp_store_template{1,:} = store_template{nim,:};
temp_deff{1,:} = deff{nim,:};
uisave({'temp_mask','temp_store_area_mask','temp_store_nx','temp_store_ny','temp_store_template','num_roi_','ntot','apply_filter_','temp_deff'});
end

end


% load old ROIs 
if load_roi == 1 
uiload 
num_roi(nim) = num_roi_;
appfilter(nim) = apply_filter_;
for j = 1:num_roi_
store_mask{nim,j} = temp_mask{1,j};
store_area_mask{nim,j} = temp_store_area_mask{1,j};
store_nx{nim,j} = temp_store_nx{1,j};
store_ny{nim,j} = temp_store_ny{1,j};
store_template{nim,j} = temp_store_template{1,j};     
deff{nim,:} = temp_deff{1,:};
end
end
    
    
    
end 












%%  Run over the total number of images
for nim = 1:num_images
filename = filename_cell{nim};
pathname = pathname_cell;
time_str = datestr(now,30);
v = VideoWriter(sprintf('video_%s_%s',filename(1:end-4),time_str),'Motion JPEG AVI');
v.Quality = 95;
v.FrameRate = 10;
open(v);
axis tight manual
tic
SA = zeros(nframes(nim),num_roi(nim));
SAN = SA; MX = NaN + SA; MY = NaN + SA; DTX = NaN + SA; DTY = NaN+SA; 
close all
for j = 1:nframes(nim)   
    
    
    
   %% load the current frame or a moving average of frames. 
  
   im_current = imread(sprintf('%s/%s',pathname,filename), j) ; % read in first image
   im_current = im2double(im_current);
   im_current = im_current(1:ntot,1:ntot);  
   im_comp = im_current;   
   
   if appfilter(nim)==1
   im_current = wiener2(im_current,[10,10]);    
   end
   
   f2 = figure(2);
   drawnow 
   
   
   
   for nroi = 1:num_roi(nim)
   mask = store_mask{nim,nroi};
   area_mask = store_area_mask{nim,nroi};
   nx = store_nx{nim,nroi};
   ny = store_ny{nim,nroi} ;
   im_template= store_template{nim,nroi};
   im_fixed = im_current(ny,nx); 
   im_comp_fixed = im_comp(ny,nx);

   
   
   if deff{nim,nroi}==1 
   [D,tformimg] = imregdemons(im_template,im_fixed,'DisplayWaitBar',false);
   [mask_warp] = double(imwarp(mask,D));
   else 
   tformimg = im_template;
   mask_warp = double(mask);     
   end
   
   %% plot the raw frame 
   subplot(num_roi(nim),4,(nroi-1)*4+1)
   imagesc(im_comp_fixed)
   daspect([1,1,1])
   set(gca,'ydir','normal')
   if nroi == 1 
   title('Raw Current Frame')
   end
   %% plot the transformed template and compute mask transform
   subplot(num_roi(nim),4,(nroi-1)*4+3)
   imagesc(tformimg)
     daspect([1,1,1])
   set(gca,'ydir','normal')
   if nroi == 1 
    title('Warped Template')   
   end
   colormap('hot')
   
   %% plot the transformed mask 
   subplot(num_roi(nim),4,(nroi-1)*4+4)
   imagesc(mask_warp + mask_warp.*area_mask,[0,2])
     daspect([1,1,1])
   set(gca,'ydir','normal')
      if nroi == 1 
    title('Warped Mask')   
   end
   
   %% plot the contour and the original image
   subplot(num_roi(nim),4,(nroi-1)*4+2)
   cf = contourc(mask_warp,[1,1]);

   cf(:,cf(1,:)>prctile(cf(1,:),99))=[];
   cf(:,cf(2,:)>prctile(cf(2,:),99))=[];
   cf(:,cf(1,:)<prctile(cf(1,:),1))=[];
   cf(:,cf(2,:)<prctile(cf(2,:),1))=[];
      
   cf = [cf,cf(:,1)];
   dt = 10;
   [midx,midy,tangx,tangy,eid]=distance_finder(cf,dt);

  
   imagesc(im_fixed), hold on 
   plot(cf(1,:),cf(2,:),'b','LineWidth',2)
   plot(midx(1,:),midx(2,:),'m','LineWidth',2)
   plot(midy(1,:),midy(2,:),'m','LineWidth',2)
   plot(tangx(1,:),tangx(2,:),'m','LineWidth',2)
   plot(tangy(1,:),tangy(2,:),'m','LineWidth',2)
   daspect([1,1,1])
   set(gca,'ydir','normal')
   SA(j,nroi) = sum(sum(mask_warp.*area_mask));
   INT(j,nroi) = sum(sum(mask_warp.*area_mask.*im_comp_fixed));
   
   
   if eid(1)==2
   MX(j,nroi) = sqrt((midx(1,1)-midx(1,2)).^2 + (midx(2,1) - midx(2,2)).^2);
   end
   if eid(2)==2
   MY(j,nroi) = sqrt((midy(1,1)-midy(1,2)).^2 + (midy(2,1) - midy(2,2)).^2);
   end
   if eid(3) == 2 
   DTX(j,nroi) = sqrt((tangx(1,1)-tangx(1,2)).^2 + (tangx(2,1) - tangx(2,2)).^2);
   end
   if eid(4) == 2 
   DTY(j,nroi) = sqrt((tangy(1,1)-tangy(1,2)).^2 + (tangy(2,1) - tangy(2,2)).^2);
   end
   
   if nroi == 1 
    title('Filtered Current Frame')   
   end
   hold off

   end
      sgtitle(sprintf('Frame Number %d',j))
   set(f2,'position',[0,0,900,300*num_roi(nim)])
   writeVideo(v,getframe(gcf))
   
end



close(v)
toc
%% 
%time = nframes/v.FrameRate; 
% 
% figure(22)
%% normalize area by template area;
 for d = 1:num_roi(nim) 
 null_area = sum(sum(store_mask{nim,d}.*store_area_mask{nim,d}));
SAN(:,d) = SA(:,d)/null_area;
 end
close all
data_table = array2table([INT,SA,SAN,MX,MY,DTX,DTY]);
var_names_temp = {'Intensity','Cross_Sectional_Area','Cross_Sectional_Area_Normalized','Horizontal_Mean_Distance','Vertical_Mean_Distance','Horizontal_Tangent_Point_Distance','Vertical_Tangent_Point_Distance'};
for i = 1:7*nroi
    roi = mod(i-1,nroi)+1;
    q = ceil(i/nroi);
    data_table.Properties.VariableNames{sprintf('Var%d',i)}=sprintf('%s_ROI_%d',var_names_temp{q},roi);

end

filename = sprintf('areas_%s_%s.xlsx',filename(1:end-4),time_str);
writetable(data_table,filename)

save(sprintf('processed_%s_%s.mat',filename(1:end-4),time_str),'-v7.3')
end