Skip to content
Snippets Groups Projects
Commit 5bff4fd4 authored by vpustova's avatar vpustova
Browse files

Update 94 files

- /InVivoTours/Result/RSULM_MatOutTours10_Gridding.mat
- /InVivoTours/Result/RSULM_MatOutTours10.tif
- /InVivoTours/Result/SRPCA_MatOutTours10.tif
- /InVivoTours/Result/SRPCA_MatOutTours4.mat
- /InVivoTours/Result/SRPCA_MatOutTours10_Gridding.mat
- /InVivoTours/Result/RSULM_MatOutTours10.mat
- /InVivoTours/Result/SRPCANonInterpTracks.mat
- /InVivoTours/Result/SRPCA_MatOutTours10.mat
- /InVivoTours/Result/MatTracks/MatTracking1.mat
- /InVivoTours/Result/MatTracks/MatTracking10.mat
- /InVivoTours/Result/MatTracks/MatTracking11.mat
- /InVivoTours/Result/MatTracks/MatTracking12.mat
- /InVivoTours/Result/MatTracks/MatTracking13.mat
- /InVivoTours/Result/MatTracks/MatTracking14.mat
- /InVivoTours/Result/MatTracks/MatTracking15.mat
- /InVivoTours/Result/MatTracks/MatTracking16.mat
- /InVivoTours/Result/MatTracks/MatTracking17.mat
- /InVivoTours/Result/MatTracks/MatTracking18.mat
- /InVivoTours/Result/MatTracks/MatTracking19.mat
- /InVivoTours/Result/MatTracks/MatTracking2.mat
- /InVivoTours/Result/MatTracks/MatTracking20.mat
- /InVivoTours/Result/MatTracks/MatTracking21.mat
- /InVivoTours/Result/MatTracks/MatTracking22.mat
- /InVivoTours/Result/MatTracks/MatTracking23.mat
- /InVivoTours/Result/MatTracks/MatTracking24.mat
- /InVivoTours/Result/MatTracks/MatTracking25.mat
- /InVivoTours/Result/MatTracks/MatTracking26.mat
- /InVivoTours/Result/MatTracks/MatTracking27.mat
- /InVivoTours/Result/MatTracks/MatTracking28.mat
- /InVivoTours/Result/MatTracks/MatTracking3.mat
- /InVivoTours/Result/MatTracks/MatTracking29.mat
- /InVivoTours/Result/MatTracks/MatTracking30.mat
- /InVivoTours/Result/MatTracks/MatTracking31.mat
- /InVivoTours/Result/MatTracks/MatTracking32.mat
- /InVivoTours/Result/MatTracks/MatTracking33.mat
- /InVivoTours/Result/MatTracks/MatTracking34.mat
- /InVivoTours/Result/MatTracks/MatTracking35.mat
- /InVivoTours/Result/MatTracks/MatTracking36.mat
- /InVivoTours/Result/MatTracks/MatTracking37.mat
- /InVivoTours/Result/MatTracks/MatTracking38.mat
- /InVivoTours/Result/MatTracks/MatTracking39.mat
- /InVivoTours/Result/MatTracks/MatTracking4.mat
- /InVivoTours/Result/MatTracks/MatTracking40.mat
- /InVivoTours/Result/MatTracks/MatTracking42.mat
- /InVivoTours/Result/MatTracks/MatTracking45.mat
- /InVivoTours/Result/MatTracks/MatTracking41.mat
- /InVivoTours/Result/MatTracks/MatTracking44.mat
- /InVivoTours/Result/MatTracks/MatTracking43.mat
- /InVivoTours/Result/MatTracks/MatTracking46.mat
- /InVivoTours/Result/MatTracks/MatTracking47.mat
- /InVivoTours/Result/MatTracks/MatTracking48.mat
- /InVivoTours/Result/MatTracks/MatTracking49.mat
- /InVivoTours/Result/MatTracks/MatTracking5.mat
- /InVivoTours/Result/MatTracks/MatTracking50.mat
- /InVivoTours/Result/MatTracks/MatTracking51.mat
- /InVivoTours/Result/MatTracks/MatTracking52.mat
- /InVivoTours/Result/MatTracks/MatTracking53.mat
- /InVivoTours/Result/MatTracks/MatTracking54.mat
- /InVivoTours/Result/MatTracks/MatTracking55.mat
- /InVivoTours/Result/MatTracks/MatTracking56.mat
- /InVivoTours/Result/MatTracks/MatTracking57.mat
- /InVivoTours/Result/MatTracks/MatTracking58.mat
- /InVivoTours/Result/MatTracks/MatTracking59.mat
- /InVivoTours/Result/MatTracks/MatTracking6.mat
- /InVivoTours/Result/MatTracks/MatTracking60.mat
- /InVivoTours/Result/MatTracks/MatTracking62.mat
- /InVivoTours/Result/MatTracks/MatTracking61.mat
- /InVivoTours/Result/MatTracks/MatTracking63.mat
- /InVivoTours/Result/MatTracks/MatTracking64.mat
- /InVivoTours/Result/MatTracks/MatTracking65.mat
- /InVivoTours/Result/MatTracks/MatTracking66.mat
- /InVivoTours/Result/MatTracks/MatTracking67.mat
- /InVivoTours/Result/MatTracks/MatTracking68.mat
- /InVivoTours/Result/MatTracks/MatTracking69.mat
- /InVivoTours/Result/MatTracks/MatTracking7.mat
- /InVivoTours/Result/MatTracks/MatTracking70.mat
- /InVivoTours/Result/MatTracks/MatTracking71.mat
- /InVivoTours/Result/MatTracks/MatTracking72.mat
- /InVivoTours/Result/MatTracks/MatTracking73.mat
- /InVivoTours/Result/MatTracks/MatTracking74.mat
- /InVivoTours/Result/MatTracks/MatTracking75.mat
- /InVivoTours/Result/MatTracks/MatTracking76.mat
- /InVivoTours/Result/MatTracks/MatTracking77.mat
- /InVivoTours/Result/MatTracks/MatTracking78.mat
- /InVivoTours/Result/MatTracks/MatTracking79.mat
- /InVivoTours/Result/MatTracks/MatTracking8.mat
- /InVivoTours/Result/MatTracks/MatTracking80.mat
- /InVivoTours/Result/MatTracks/MatTracking9.mat
- /InVivoTours/Fig6ac_InVivoTours_RSULM.m
- /InVivoTours/Fig6db_InVivoTours_SRPCA.m
- /InVivoTours/psf10Tours.mat
- /InVivoTours/psfSR4_Tours.mat
- /InVivoTours/SRPCATours.m
- /InVivoTours/ULM_localization2DSR_Tours.m
parent f98fb140
Branches
No related tags found
No related merge requests found
Showing
with 598 additions and 0 deletions
%% InVivoTours_RSULM.m
%
%
% Based on the code created by Arthur Chavignon
% Adapted for the WKY in vivo data.
%
% DATE 2020.12.17 - VERSION 1.1
% AUTHORS: Arthur Chavignon, Baptiste Heiles, Vincent Hingot. CNRS, Sorbonne Universite, INSERM.
% Laboratoire d'Imagerie Biomedicale, Team PPM. 15 rue de l'Ecole de Medecine, 75006, Paris
% Code Available under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (see https://creativecommons.org/licenses/by-nc-sa/4.0/)
% ACADEMIC REFERENCES TO BE CITED
% Details of the code in the article by Heiles, Chavignon, Hingot, Lopez, Teston and Couture.
% Performance benchmarking of microbubble-localization algorithms for ultrasound localization microscopy, Nature Biomedical Engineering, 2021.
% General description of super-resolution in: Couture et al., Ultrasound localization microscopy and super-resolution: A state of the art, IEEE UFFC 2018
clear
%cd ./..
PALA_folder = fileparts(pwd); % location of the PALA folder
PALA_data_folder = fullfile(PALA_folder, 'PALA_data_folder');
% DEFINE THE ADDONS DIRECTORY ON YOUR COMPUTER
addpath(genpath(fullfile(PALA_folder, 'PALA_addons')));
%% Adapt parameters to your data
% A few parameters must be provided by the user depending of your input images (size of pixel, wavelength)
% These parameters will be copied and used later during the creation of the ULM structure.
% in this example, UF.TwFreq = 15MHz, UF.FrameRateUF = 1000Hz;
UF.TwFreq = 14.8;
UF.FrameRateUF = 1000;
% Here you put the size of your data
SizeOfBloc = [160 128 500];
% Here you put the size of pixel in the prefered unit. It can be um, mm, m, wavelength, or an arbitrary scale.
ScaleOfPixel = [1 1]; % [pixel_size_z, pixel_size_x]
% In that example, the size of pixels is lambda x lambda. The localization process will be
% performs in wavelength. For velocity rendering, velocities in [wavelength/s] will be converted in [mm/s].
% The imaging frame rate is required for velocity calculation, and temporal filtering.
framerate = 1000; % imaging framerate in [Hz]
% Number of blocs to process
Nbuffers = 80; % number of bloc to process (used in the parfor)
% If pixel sizes are in wavelength, lambda must be provided for a velocity maps in mm/s,
lambda = 1480/(UF.TwFreq*1e3);
%% ULM parameters
% this script can be run using different scaling, it can be wavelength, pixel size, mm, um.
% In this example, input pixel are isotropic and equal to lambda (pixelPitch_x = pixelPitch_y = lambda)
% All size defined later are expressed in lambda
res = 10; % final ratio of localization rendering, it's approximately resolution factor of localization in scale(1) units.
% for a pixel size of 100um, we can assume that ULM algorithm provides precision 10 (res) times
% smaller than pixel size. Final rendering will be reconstructed on a 10x10um grid.
ULM = struct('numberOfParticles', 90,... % Number of particles per frame. (30-100)
'size',[SizeOfBloc(1) SizeOfBloc(2) SizeOfBloc(3)],... % size of input data [nb_pixel_z nb_pixel_x nb_frame_per_bloc]
'scale',[ScaleOfPixel 1/framerate],...% Scale [z x dt], size of pixel in the scaling unit. (here, pixsize = 1*lambda)
'res',res,... % Resolution factor. Typically 10 for final image rendering at lambda/10.
'SVD_cutoff',[5 SizeOfBloc(3)],... % SVD filtering, to be adapted to your clutter/SNR levels
'max_linking_distance',2,... % Maximum linking distance between two frames to reject pairing, in pixels units (UF.scale(1)). (2-4 pixel).
'min_length', 15,... % Minimum allowed length of the tracks in time. (5-20 frames)
'fwhm',[1 1]*3,... % Size [pixel] of the mask for localization. (3x3 for pixel at lambda, 5x5 at lambda/2). [fmwhz fmwhx]
'max_gap_closing', 0,... % Allowed gap in microbubbles' pairing. (if you want to skip frames 0)
'interp_factor',1/res,... % Interpfactor (decimation of tracks)
'LocMethod','Radial'... % Select localization algorithm (WA,Interp,Radial,CurveFitting,NoLocalization)
);
ULM.ButterCuttofFreq = [50 249]; % Cutoff frequency (Hz) for additional filter. Typically [20 300] at 1kHz.
ULM.parameters.NLocalMax = 3; % Safeguard on the number of maxLocal in the fwhm*fwhm grid (3 for fwhm=3, 7 for fwhm=5)
[but_b,but_a] = butter(2,ULM.ButterCuttofFreq/(framerate/2),'bandpass');
ULM.lambda = lambda;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Load data and localize microbubbles %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Track_tot = {};
fprintf('--- ULM PROCESSING --- \n\n');t1=tic;
for hhh = 1:Nbuffers
fprintf('Processing bloc %d/%d\n',hhh,Nbuffers);
% Load IQ data
tmp = load(strcat(PALA_data_folder,'/IQTours/IQTours_',int2str(hhh),'.mat'),'IQ');
tmp.IQ = tmp.IQ(5:164,:,:);
% Filtering of IQ to remove clutter (optional)
IQ_filt = SVDfilter(tmp.IQ,ULM.SVD_cutoff);tmp = [];
% Temporal filtering
IQ_filt = filter(but_b,but_a,IQ_filt,[],3); %(optional)
IQ_filt(~isfinite(IQ_filt))=0;
% Detection and localization process (return a list of coordinates in pixel)
[MatTracking] = ULM_localization2D(abs(IQ_filt),ULM); IQ_filt=[];
% Convert pixel into isogrid (pixel are not necessary isometric);
MatTracking(:,2:3) = (MatTracking(:,2:3) - [1 1]).*ULM.scale(1:2);
% Tracking algorithm (list of tracks)
Track_tot_i = ULM_tracking2D(MatTracking,ULM);
Track_tot{hhh} = Track_tot_i;
Track_tot_i={};MatTracking = [];
end
Track_tot = cat(1,Track_tot{:});
Tend = toc(t1);disp('Done')
fprintf('ULM done in %d hours %.1f minutes.\n', floor(Tend/60/60), rem(Tend/60,60));
%% Create individual variable to save using v6 version.
% By cutting Tracks into different variables small than 2GB, the save v6 is faster than save v7.3
% CutTracks = round(linspace(1,numel(Track_tot),4));
% Track_tot_1 = Track_tot(CutTracks(1):CutTracks(2)-1);
% Track_tot_2 = Track_tot(CutTracks(2):CutTracks(3)-1);
% Track_tot_3 = Track_tot(CutTracks(3):end);
% save(['example_tracks.mat'],'Track_tot_1','Track_tot_2','Track_tot_3','Tend','ULM','-v6')
% clear Track_tot_1 Track_tot_2 Track_tot_3
% load([workingdir filesep filename 'example_tracks.mat'])
% Track_tot = cat(1,Track_tot_1,Track_tot_2,Track_tot_3);clear Track_tot_1 Track_tot_2 Track_tot_3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Create MatOut %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% create the MatOut density with interpolated tracks for visual analysis, and with non interpolated tracks for aliasing index calculation.
% Define the size of SRpixel for displaying (default 10)
ULM.SRscale = ULM.scale(1)/ULM.res;
ULM.SRsize = round(ULM.size(1:2).*ULM.scale(1:2)/ULM.SRscale);
% Convert tracks into SRpixel
Track_matout = cellfun(@(x) (x(:,[1 2 3 4])+[1 1 0 0]*1)./[ULM.SRscale ULM.SRscale 1 1],Track_tot,'UniformOutput',0);
llz = [0:ULM.SRsize(1)]*ULM.SRscale;llx = [0:ULM.SRsize(2)]*ULM.SRscale;
%% Accumulate tracks on the final MatOut grid.
% fprintf('--- CREATING MATOUTS --- \n\n')
MatOut = ULM_Track2MatOut(Track_matout,ULM.SRsize+[1 1]*1); %pos in superpix [z x]
MatOut_zdir = ULM_Track2MatOut(Track_matout,ULM.SRsize+[1 1]*1,'mode','2D_vel_z'); %pos in superpix [z x]
MatOut_vel = ULM_Track2MatOut(Track_matout,ULM.SRsize+[1 1]*1,'mode','2D_velnorm'); %pos in superpix [z x]
MatOut_vel = MatOut_vel*ULM.lambda; % Convert into [mm/s]
save(strcat(pwd,'/Result/RSULM_MatOutTours10.mat'),'MatOut','MatOut_zdir','MatOut_vel','ULM','lambda','llx','llz')
%% Figures
ULM.SRscale=0.625/ULM.res; %for velocity maps in mm/s and scale-bars
maxSRPCA = 64;
IntPower = 1/2.3;
cmin = min(MatOut(:).^IntPower);
cmax = max(MatOut(:).^IntPower);
numTicks = 7; % Adjust as needed
h1=figure('WindowState', 'maximized');
im=imagesc((MatOut).^IntPower);
axis image
colormap hot
clbar = colorbar;
set(clbar, 'YTick', linspace(cmin, cmax, numTicks));
clbar.Label.String = 'Normalized localization density';
%clbar.TickLabels = clbar.Ticks.^2.3; %Not normalized
clbar.TickLabels = round(clbar.Ticks.^2.3 ./ maxSRPCA, 2);
set(gca,'XColor', 'none','YColor','none')
set(gca, 'color', 'none');
BarWidth = round(1./(ULM.SRscale*lambda)); % 1 mm
im.CData(size(MatOut,1)-50+[0:2],60+[0:BarWidth])=max(clim);
text(60+BarWidth/2, size(MatOut,1)-50+3 +15, '1 mm', ...
'Color', 'w', 'FontSize', 12, 'FontWeight', 'bold', ...
'HorizontalAlignment', 'center');
% Smaller Colorbar
% If there is a display issue, try executing the code below separately
% after you created the figure h1 as it depends on your screen size
% x1=get(gca,'position');
% x=get(clbar,'Position');
% x(1)=x(1)-0.003;
% x(3)=0.005;
% set(clbar,'Position',x)
% set(gca,'position',x1)
% clbar.Label.Position = [x(1)+2.5, x(2)+clbar.Ticks(end)/2, x(3)];
%%
IntPower = 1/2.3;
OriginalData = MatOut.^IntPower.*sign(imgaussfilt(MatOut_zdir,.8));
cmin = min(OriginalData(:));
cmax = max(OriginalData(:));
clear OriginalData;
numTicks = 9; % Adjust as needed
figure('WindowState', 'maximized');
velColormap = cat(1,flip(flip(hot(128),1),2),hot(128));
velColormap = velColormap(5:end-5,:);
im=imagesc(llx,llz,(MatOut).^IntPower.*sign(imgaussfilt(MatOut_zdir,.8)))
im.CData = im.CData - sign(im.CData)/2;axis image
colormap(gca,velColormap)
clbar = colorbar;
set(clbar, 'YTick', linspace(cmin*0.90, cmax*0.90, numTicks));
clbar.Label.String = 'Normalized localization density';
clbar.Ticks = clbar.Ticks;%customTicks;
TempTickLabels = round(sign(clbar.Ticks).*abs(clbar.Ticks/0.90).^2.3);
clbar.TickLabels = round(TempTickLabels ./ maxSRPCA,2);
set(gca,'XColor', 'none','YColor','none')
set(gca, 'color', 'none');
caxis([-1 1]*max(caxis)*.75)
BarWidth = round(1./(ULM.SRscale*lambda)); % 1 mm
im.CData(size(MatOut,1)-50+[0:3],60+[0:BarWidth])=max(caxis);
% Smaller Colorbar
% If there is a display issue, try executing the code below separately
% after you created the figure h1 as it depends on your screen size
% x1=get(gca,'position');
% x=get(clbar,'Position');
% x(1)=x(1)-0.003;
% x(3)=0.005;
% set(clbar,'Position',x)
% set(gca,'position',x1)
% clbar.Label.Position = [x(1)+2.5, x(2), x(3)];
%%
%vmax_disp = ceil(quantile(MatOut_vel(abs(MatOut_vel)>0),.98)/10)*10;
vmax_disp = 80;
h1=figure('WindowState', 'maximized'); clf,set(gcf,'Position',[652 393 941 585]);
clbsize = [180,50];
Mvel_rgb = MatOut_vel/vmax_disp; % normalization
% Mvel_rgb(1:clbsize(1),1:clbsize(2)) = repmat(linspace(1,0,clbsize(1))',1,clbsize(2)); % add velocity colorbar
Mvel_rgb = Mvel_rgb.^(1/2);Mvel_rgb(Mvel_rgb>1)=1;
Mvel_rgb = imgaussfilt(Mvel_rgb,.5);
Mvel_rgb = ind2rgb(round(Mvel_rgb*256),jet(256)); % convert ind into RGB
IntPower = 1/2.3;
MatShadow = MatOut;MatShadow = MatShadow./max(MatShadow(:)*.3);MatShadow(MatShadow>1)=1;
%MatShadow(1:clbsize(1),1:clbsize(2))=repmat(linspace(0,1,clbsize(2)),clbsize(1),1);
Mvel_rgb = Mvel_rgb.*(MatShadow.^IntPower);
Mvel_rgb = brighten(Mvel_rgb,.4);
im=imshow(Mvel_rgb,'XData',llx,'YData',llz);axis on
BarWidth = round(1./(ULM.SRscale*lambda)); % 1 mm
im.CData(size(MatOut,1)-50+[0:3],60+[0:BarWidth],1:3)=1;
set(gca,'XColor', 'none','YColor','none')
set(gca, 'color', 'none');
colormap(jet);
clbar = colorbar;
clim([0 vmax_disp]);
clbar.Label.String = 'Velocity magnitude (mm/s)';
% Smaller Colorbar
% If there is a display issue, try executing the code below separately
% after you created the figure h1 as it depends on your screen size
% x1=get(gca,'position');
% x=get(clbar,'Position');
% x(1)=x(1)-0.003;
% x(3)=0.005;
% set(clbar,'Position',x)
% set(gca,'position',x1)
% clbar.Label.Position = [x(1)+2.5, x(2)+clbar.Ticks(end)/2, x(3)];
%% Metrics
% Saturation Value
% load(strcat(pwd,'/Result/RSULM_MatOutTours10.mat'),'MatOut')
Saturation = nnz(MatOut()>0)/numel(MatOut());
% CR
% load(strcat(pwd,'/Result/RSULM_MatOutTours10.mat'),'MatOut')
CR = ContrastRatio(MatOut);
% Image for FRC estimation
% load(strcat(pwd,'/Result/RSULM_MatOutTours10.mat'),'MatOut')
figure(1);
IntPower = 1/2.3;
im=imagesc(llx,llz,MatOut.^IntPower);axis image
set(gca,'XColor', 'none','YColor','none')
set(gca, 'color', 'none');
im.CData = max(im.CData-.5,0);
colormap(gca,gray(128))
caxis(caxis*.7) % add saturation in image
ca = gca;
WriteTif(im.CData,ca.Colormap,strcat(pwd,'/Result/RSULM_MatOutTours10.tif'),'caxis',caxis,'Overwrite',1)
% Gridding index
load(strcat(pwd,'/Result/RSULM_MatOutTours10_Gridding.mat'),'MatOut')
Gridding_index = PALA_ComputeGriddingIndex({MatOut},1);
Gridding = 1-Gridding_index/30; % [100 at 0; 0 at -30]
%% InVivoTours_SRPCA.m
%
%
% Based on the code created by Arthur Chavignon
% Adapted for the WKY in vivo data.
%
% DATE 2020.12.17 - VERSION 1.1
% AUTHORS: Arthur Chavignon, Baptiste Heiles, Vincent Hingot. CNRS, Sorbonne Universite, INSERM.
% Laboratoire d'Imagerie Biomedicale, Team PPM. 15 rue de l'Ecole de Medecine, 75006, Paris
% Code Available under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (see https://creativecommons.org/licenses/by-nc-sa/4.0/)
% ACADEMIC REFERENCES TO BE CITED
% Details of the code in the article by Heiles, Chavignon, Hingot, Lopez, Teston and Couture.
% Performance benchmarking of microbubble-localization algorithms for ultrasound localization microscopy, Nature Biomedical Engineering, 2021.
% General description of super-resolution in: Couture et al., Ultrasound localization microscopy and super-resolution: A state of the art, IEEE UFFC 2018
clear
%cd ./..
PALA_folder = fileparts(pwd); % location of the PALA folder
PALA_data_folder = fullfile(PALA_folder, 'PALA_data_folder');
% DEFINE THE ADDONS DIRECTORY ON YOUR COMPUTER
addpath(genpath(fullfile(PALA_folder, 'PALA_addons')));
%% Adapt parameters to your data
% A few parameters must be provided by the user depending of your input images (size of pixel, wavelength)
% These parameters will be copied and used later during the creation of the ULM structure.
% in this example, UF.TwFreq = 15MHz, UF.FrameRateUF = 1000Hz;
SR = 10; %Super Resolution factor
UF.TwFreq = 14.8;
UF.FrameRateUF = 1000;
% Here you put the size of your data
SizeOfBloc = [SR*160 SR*128 500];
% Here you put the size of pixel in the prefered unit. It can be um, mm, m, wavelength, or an arbitrary scale.
ScaleOfPixel = [1 1]; % [pixel_size_z, pixel_size_x]
% In that example, the size of pixels is lambda x lambda. The localization process will be
% performs in wavelength. For velocity rendering, velocities in [wavelength/s] will be converted in [mm/s].
% The imaging frame rate is required for velocity calculation, and temporal filtering.
framerate = 1000; % imaging framerate in [Hz]
% Number of blocs to process
Nbuffers = 80; % number of bloc to process (used in the parfor)
% If pixel sizes are in wavelength, lambda must be provided for a velocity maps in mm/s,
lambda = 1480/(UF.TwFreq*1e3); % lambda = 1.002031144211239e-1
%% ULM parameters
% this script can be run using different scaling, it can be wavelength, pixel size, mm, um.
% In this example, input pixel are isotropic and equal to lambda (pixelPitch_x = pixelPitch_y = lambda)
% All size defined later are expressed in lambda
res = SR; % final ratio of localization rendering, it's approximately resolution factor of localization in scale(1) units.
% for a pixel size of 100um, we can assume that ULM algorithm provides precision 10 (res) times
% smaller than pixel size. Final rendering will be reconstructed on a 10x10um grid.
ULM = struct('numberOfParticles', 70,... % Number of particles per frame. (30-100)
'size',[SizeOfBloc(1) SizeOfBloc(2) SizeOfBloc(3)],... % size of input data [nb_pixel_z nb_pixel_x nb_frame_per_bloc]
'scale',[ScaleOfPixel 1/framerate],...% Scale [z x dt], size of pixel in the scaling unit. (here, pixsize = 1*lambda)
'res',res,... % Resolution factor. Typically 10 for final image rendering at lambda/10.
'SVD_cutoff',[25 SizeOfBloc(3)],... % SVD filtering, to be adapted to your clutter/SNR levels
'max_linking_distance',2,... % Maximum linking distance between two frames to reject pairing, in pixels units (UF.scale(1)). (2-4 pixel).
'min_length', 10,... % Minimum allowed length of the tracks in time. (5-20 frames)
'fwhm',[1 1]*7,... % Size [pixel] of the mask for localization. (3x3 for pixel at lambda, 5x5 at lambda/2). [fmwhz fmwhx]
'max_gap_closing', 1,... % Allowed gap in microbubbles' pairing. (if you want to skip frames 0)
'interp_factor',1/res,... % Interpfactor (decimation of tracks)
'LocMethod','Radial'... % Select localization algorithm (WA,Interp,Radial,CurveFitting,NoLocalization)
);
ULM.ButterCuttofFreq = [50 249]; % Cutoff frequency (Hz) for additional filter. Typically [20 300] at 1kHz.
ULM.parameters.NLocalMax = 3; % Safeguard on the number of maxLocal in the fwhm*fwhm grid (3 for fwhm=3, 7 for fwhm=5)
[but_b,but_a] = butter(2,ULM.ButterCuttofFreq/(framerate/2),'bandpass');
ULM.lambda = lambda; % Safeguard on the number of maxLocal in the fwhm*fwhm grid (3 for fwhm=3, 7 for fwhm=5)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Load data and localize microbubbles %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
myfun= @SRPCATours;
blksz = [336 272 500];
Track_tot = {};
fprintf('--- ULM PROCESSING --- \n\n');t1=tic;
for hhh = 1:Nbuffers
pixOffset = 2*floor((hhh-1) / 5) ;
fprintf('Processing bloc %d/%d\n',hhh,Nbuffers);
% Load IQ data
tmp = load(strcat(PALA_data_folder,'/IQTours/IQTours_',int2str(hhh),'.mat'),'IQ');
tmp.IQ = tmp.IQ(5:164,:,:);
tmp.IQ = imresize(tmp.IQ,SR,"bicubic");
% Temporal filter
tmp.IQ = filter(but_b,but_a,tmp.IQ,[],3); %(optional)
tmp.IQ(~isfinite(tmp.IQ))=0;
IQ = tmp.IQ/max(abs(tmp.IQ(:)));tmp = [];
IQ = padarray(IQ, [40 40]);
IQ = circshift(IQ, [-pixOffset -pixOffset]);
IQ_filt = blockproc3(IQ, blksz, myfun, [40 40 0]); IQ = [];
IQ_filt = circshift(IQ_filt, [pixOffset pixOffset]);
IQ_filt=IQ_filt(41:end-40,41:end-40,:);
% Detection process (return a list of super resolved coordinates in pixel)
[MatTracking] = ULM_localization2DSR_Tours(abs(IQ_filt),ULM,pixOffset); IQ_filt=[];
% Normalize for tracking
MatTracking(:,2:3) = MatTracking(:,2:3)/SR;
% Convert pixel into isogrid (pixel are not necessary isometric);
MatTracking(:,2:3) = (MatTracking(:,2:3) - [1 1]).*ULM.scale(1:2);
%save([pwd,'/Result/MatTracking',int2str(hhh),'.mat'],'MatTracking')
% Tracking algorithm (list of tracks)
Track_tot_i = ULM_tracking2D(MatTracking,ULM);
Track_tot{hhh} = Track_tot_i;
Track_tot_i={};MatTracking = [];
end
Track_tot = cat(1,Track_tot{:});
Tend = toc(t1);disp('Done')
fprintf('ULM done in %d hours %.1f minutes.\n', floor(Tend/60/60), rem(Tend/60,60));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ULM.SRscale = ULM.scale(1)/ULM.res;
ULM.SRsize = round(ULM.size(1:2).*ULM.scale(1:2));
%
% % Convert tracks into SRpixel
Track_matout = cellfun(@(x) (x(:,[1 2 3 4])+[1 1 0 0]*1)./[ULM.SRscale ULM.SRscale 1 1],Track_tot,'UniformOutput',0);
llz = [0:ULM.SRsize(1)]*ULM.SRscale;llx = [0:ULM.SRsize(2)]*ULM.SRscale;
%% Accumulate tracks on the final MatOut grid.
% fprintf('--- CREATING MATOUTS --- \n\n')
MatOut = ULM_Track2MatOut(Track_matout,ULM.SRsize+[1 1]*1); %pos in superpix [z x]
MatOut_zdir = ULM_Track2MatOut(Track_matout,ULM.SRsize+[1 1]*1,'mode','2D_vel_z'); %pos in superpix [z x]
MatOut_vel = ULM_Track2MatOut(Track_matout,ULM.SRsize+[1 1]*1,'mode','2D_velnorm'); %pos in superpix [z x]
MatOut_vel = MatOut_vel*ULM.lambda; % Convert into [mm/s]
save(strcat(pwd,'/Result/SRPCA_MatOutTours10.mat'),'MatOut','MatOut_zdir','MatOut_vel','ULM','lambda','llx','llz')
%% Figures
ULM.SRscale=0.625/ULM.res; %for velocity maps in mm/s and scale-bars
IntPower = 1/2.3;
cmin = min(MatOut(:).^IntPower);
cmax = max(MatOut(:).^IntPower);
numTicks = 7; % Adjust as needed
h1=figure('WindowState', 'maximized');
im=imagesc((MatOut).^IntPower);
axis image
colormap hot
clbar = colorbar;
set(clbar, 'YTick', linspace(cmin, cmax, numTicks));
clbar.Label.String = 'Normalized localization density';
%clbar.TickLabels = clbar.Ticks.^2.3; %Not normalized
clbar.TickLabels = round(clbar.Ticks.^2.3 ./ max(clbar.Ticks(:).^2.3),2);
set(gca,'XColor', 'none','YColor','none')
set(gca, 'color', 'none');
BarWidth = round(1./(ULM.SRscale*lambda)); % 1 mm
im.CData(size(MatOut,1)-50+[0:2],60+[0:BarWidth])=max(clim);
text(60+BarWidth/2, size(MatOut,1)-50+3 +15, '1 mm', ...
'Color', 'w', 'FontSize', 12, 'FontWeight', 'bold', ...
'HorizontalAlignment', 'center');
% Smaller Colorbar
% If there is a display issue, try executing the code below separately
% after you created the figure h1 as it depends on your screen size
% x1=get(gca,'position');
% x=get(clbar,'Position');
% x(1)=x(1)-0.003;
% x(3)=0.005;
% set(clbar,'Position',x)
% set(gca,'position',x1)
% clbar.Label.Position = [x(1)+2.5, x(2)+clbar.Ticks(end)/2, x(3)];
%%
IntPower = 1/2.3;
OriginalData = MatOut.^IntPower.*sign(imgaussfilt(MatOut_zdir,.8));
cmin = min(OriginalData(:));
cmax = max(OriginalData(:));
clear OriginalData;
numTicks = 9; % Adjust as needed
h1=figure('WindowState', 'maximized');
velColormap = cat(1,flip(flip(hot(128),1),2),hot(128));
velColormap = velColormap(5:end-5,:);
im=imagesc(llx,llz,(MatOut).^IntPower.*sign(imgaussfilt(MatOut_zdir,.8)))
im.CData = im.CData - sign(im.CData)/2;axis image
colormap(gca,velColormap)
clbar = colorbar;
set(clbar, 'YTick', linspace(cmin*0.90, cmax*0.90, numTicks));
clbar.Label.String = 'Normalized localization density';
clbar.Ticks = clbar.Ticks;%customTicks;
TempTickLabels = round(sign(clbar.Ticks).*abs(clbar.Ticks/0.90).^2.3);
clbar.TickLabels = round(TempTickLabels ./ max(TempTickLabels(:)),2);
set(gca,'XColor', 'none','YColor','none')
set(gca, 'color', 'none');
caxis([-1 1]*max(caxis)*.75)
BarWidth = round(1./(ULM.SRscale*lambda)); % 1 mm
im.CData(size(MatOut,1)-50+[0:3],60+[0:BarWidth])=max(caxis);
% Smaller Colorbar
% If there is a display issue, try executing the code below separately
% after you created the figure h1 as it depends on your screen size
% x1=get(gca,'position');
% x=get(clbar,'Position');
% x(1)=x(1)-0.003;
% x(3)=0.005;
% set(clbar,'Position',x)
% set(gca,'position',x1)
% clbar.Label.Position = [x(1)+2.5, x(2), x(3)];
%%
%vmax_disp = ceil(quantile(MatOut_vel(abs(MatOut_vel)>0),.98)/10)*10;
vmax_disp = 80;
h1=figure('WindowState', 'maximized'); clf,set(gcf,'Position',[652 393 941 585]);
clbsize = [180,50];
Mvel_rgb = MatOut_vel/vmax_disp; % normalization
% Mvel_rgb(1:clbsize(1),1:clbsize(2)) = repmat(linspace(1,0,clbsize(1))',1,clbsize(2)); % add velocity colorbar
Mvel_rgb = Mvel_rgb.^(1/2);Mvel_rgb(Mvel_rgb>1)=1;
Mvel_rgb = imgaussfilt(Mvel_rgb,.5);
Mvel_rgb = ind2rgb(round(Mvel_rgb*256),jet(256)); % convert ind into RGB
IntPower = 1/2.3;
MatShadow = MatOut;MatShadow = MatShadow./max(MatShadow(:)*.3);MatShadow(MatShadow>1)=1;
%MatShadow(1:clbsize(1),1:clbsize(2))=repmat(linspace(0,1,clbsize(2)),clbsize(1),1);
Mvel_rgb = Mvel_rgb.*(MatShadow.^IntPower);
Mvel_rgb = brighten(Mvel_rgb,.4);
im=imshow(Mvel_rgb,'XData',llx,'YData',llz);axis on
BarWidth = round(1./(ULM.SRscale*lambda)); % 1 mm
im.CData(size(MatOut,1)-50+[0:3],60+[0:BarWidth],1:3)=1;
set(gca,'XColor', 'none','YColor','none')
set(gca, 'color', 'none');
colormap(jet);
clbar = colorbar;
clim([0 vmax_disp]);
clbar.Label.String = 'Velocity magnitude (mm/s)';
% Smaller Colorbar
% If there is a display issue, try executing the code below separately
% after you created the figure h1 as it depends on your screen size
% x1=get(gca,'position');
% x=get(clbar,'Position');
% x(1)=x(1)-0.003;
% x(3)=0.005;
% set(clbar,'Position',x)
% set(gca,'position',x1)
% clbar.Label.Position = [x(1)+2.5, x(2)+clbar.Ticks(end)/2, x(3)];
%% Metrics
% Saturation Value
% load(strcat(pwd,'/Result/SRPCA_MatOutTours10.mat'),'MatOut')
Saturation = nnz(MatOut()>0)/numel(MatOut());
% CR
% load(strcat(pwd,'/Result/SRPCA_MatOutTours10.mat'),'MatOut')
CR = ContrastRatio(MatOut);
% Image for FRC estimation
% load(strcat(pwd,'/Result/SRPCA_MatOutTours10.mat'),'MatOut')
figure(1);
IntPower = 1/2.3;
im=imagesc(llx,llz,MatOut.^IntPower);axis image
% im=imagesc(llx,llz,PowDop2);axis image
set(gca,'XColor', 'none','YColor','none')
set(gca, 'color', 'none');
im.CData = max(im.CData-.5,0);
colormap(gca,gray(128))
caxis(caxis*.7) % add saturation in image
ca = gca;
WriteTif(im.CData,ca.Colormap,strcat(pwd,'/Result/SRPCA_MatOutTours10.tif'),'caxis',caxis,'Overwrite',1)
% Gridding index
load(strcat(pwd,'/Result/SRPCA_MatOutTours10_Gridding.mat'),'MatOut')
Gridding_index = PALA_ComputeGriddingIndex({MatOut},1);
Gridding = 1-Gridding_index/30; % [100 at 0; 0 at -30]
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment