Skip to content

Commit

Permalink
up
Browse files Browse the repository at this point in the history
  • Loading branch information
vergaloy committed Sep 6, 2024
1 parent 0e64194 commit f37e9ff
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 116 deletions.
32 changes: 22 additions & 10 deletions Align_sessions/align_sessions_CaliAli.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,27 @@ function align_sessions_CaliAli(varargin)
[P2,opt.T,opt.T_Mask]=sessions_translate(P1);
fprintf(1, 'Calculating non-rigid aligments...\n');
[opt.shifts,P3,opt.NR_Mask]=get_shifts_alignment(P2);
[opt.shifts_n,P4,opt.NR_Mask_n]=get_shifts_alignment_only_neurons(P3);
P=table(P1,P2,P3,P4,'VariableNames',{'Original','Translations','Multi-Scale','Final'});
if opt.FinalAlignmentWithNeuronShapes
[opt.shifts_n,P4,opt.NR_Mask_n]=get_shifts_alignment_only_neurons(P3);
P=table(P1,P2,P3,P4,'VariableNames',{'Original','Translations','CaliAli','CaliAli+neurons'});
else
P=table(P1,P2,P3,'VariableNames',{'Original','Translations','CaliAli'});
end
P=BV_gray2RGB(P);
if opt.UseBV==1
[P,opt]=evaluate_BV(P,opt);
end

T=get_alignment_metrics(P);
T
apply_transformations(opt);
save_relevant_variables(P,opt)
save_relevant_variables(P,opt,T)
end

function [P,opt]=evaluate_BV(P,opt)
opt.BV_score=get_BV_NR_score(P,2);
fprintf(1, 'Blood-vessel similarity score: %1.3f \n',opt.BV_score);
if opt.BV_score<2.7
if opt.BV_score<2.7 && opt.Force_BVz==0
fprintf(2, 'Blood-vessel similarity score is too low! \n Results may not be accurate! \n ');
fprintf(2, 'Aligning utilizing neurons data \n ');
P1=P.(1)(1,:);
Expand All @@ -37,24 +44,29 @@ function align_sessions_CaliAli(varargin)
fprintf(1, 'Calculating non-rigid aligments...\n');
[opt.shifts,P3,opt.NR_Mask]=get_shifts_alignment(P2);
[opt.shifts_n,P4,opt.NR_Mask_n]=get_shifts_alignment_only_neurons(P3);
P=table(P1,P2,P3,P4,'VariableNames',{'Original','Translations','Multi-Scale','Final'});
if opt.FinalAlignmentWithNeuronShapes
[opt.shifts_n,P4,opt.NR_Mask_n]=get_shifts_alignment_only_neurons(P3);
P=table(P1,P2,P3,P4,'VariableNames',{'Original','Translations','CaliAli','CaliAli+neurons'});
else
P=table(P1,P2,P3,'VariableNames',{'Original','Translations','CaliAli'});
end
P=BV_gray2RGB(P);
end
get_neuron_projections_correlations(P,3);
end

function save_relevant_variables(P,opt)
Cn=max(P.(4)(1,:).(3){1,1},[],3);
function save_relevant_variables(P,opt,T)
Cn=max(P.(size(P,2))(1,:).(3){1,1},[],3);
opt.Cn_scale=max(Cn,[],'all');
Cn=Cn./opt.Cn_scale;
PNR=max(P.(4)(1,:).(4){1,1},[],3);
PNR=max(P.(size(P,2))(1,:).(4){1,1},[],3);
BV_score=opt.BV_score;
F=opt.F;
n_enhanced=opt.n_enhanced;
if ~isfile(opt.out_mat)
save(opt.out_mat,'P','BV_score','Cn','PNR','F','n_enhanced','opt');
save(opt.out_mat,'P','BV_score','Cn','PNR','F','n_enhanced','opt','T');
else
save(opt.out_mat,'P','BV_score','Cn','PNR','F','n_enhanced','opt','-append');
save(opt.out_mat,'P','BV_score','Cn','PNR','F','n_enhanced','opt','-append','T');
end
end

4 changes: 3 additions & 1 deletion Align_sessions/apply_transformations.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ function apply_transformations(varargin)
Vid=h5read(fullFileName,'/Object');
Vid=apply_translations(Vid,opt.T(k,:),opt.T_Mask);
Vid=apply_NR_shifts(Vid,opt.shifts(:,:,:,k),opt.NR_Mask);
Vid=apply_NR_shifts(Vid,opt.shifts_n(:,:,:,k),opt.NR_Mask_n);
if opt.FinalAlignmentWithNeuronShapes
Vid=apply_NR_shifts(Vid,opt.shifts_n(:,:,:,k),opt.NR_Mask_n);
end
if isa(Vid,'uint16')
Vid=uint16(single(Vid).*R(k));
else
Expand Down
79 changes: 0 additions & 79 deletions Align_sessions/get_Vf_vignetting_fixed.asv

This file was deleted.

25 changes: 25 additions & 0 deletions Align_sessions/get_alignment_metrics.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
function T=get_alignment_metrics(P)

T=table();
Name={'Non-aligned','Translations','CaliAli','CaliAli+Neuron alignment'};
for i=1:size(P,2)
Neuo=mat2gray(squeeze(P.(i)(1,:).(5){1,1}(:,:,1,:)));
T=[T;create_table(Neuo,Name{i},'Neurons')];
end
%
% for i=1:size(P,2)
% BVo=mat2gray(P.(i)(1,:).BloodVessels{1,1});
% T=[T;create_table(BVo,Name{i},'BV')];
% end

end


function out=create_table(in,reference_projection,test_projection)
pr=get_matched_projection(in);
[c,~,s] = motion_metrics(in);
out=table(categorical(string(reference_projection)),categorical(string(test_projection)),{pr},{c},mean(c),s, ...
'VariableNames',{'Transformation','Test. Projection','Aligned Projections','Correlation scores','Mean Corr. Score','Crispness'});
end


11 changes: 11 additions & 0 deletions Align_sessions/get_matched_projection.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function out=get_matched_projection(in)
ref=in(:,:,round(size(in,3)/2));

for i=1:size(in,3)
J = localHistMatch(mat2gray(ref), mat2gray(in(:,:,i)), [100,100], [50,50],0.001);
A=mat2gray(in(:,:,i));
k=mat2gray(imgaussfilt(medfilt2(mat2gray(histeq(A.*J)).*mat2gray(ref),[4,4])));
out(:,:,:,i)=cat(3,max(cat(3,A,k),[],3),max(cat(3,J,k),[],3),J*0);
end


58 changes: 58 additions & 0 deletions Align_sessions/int_var.asv
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
function opt=int_var(varargin)
%% INTIALIZE VARIABLES
inp = inputParser;
valid_v = @(x) isnumeric(x);
addParameter(inp,'gSig',2.5,valid_v) %Neuron Filter size. 2.5 default.
addParameter(inp,'sf',10,valid_v) %Frame rate. Defualt 10 fps
addParameter(inp,'n_enhanced',1) %MIN1PIE background substraciton. True is recommended. default True
addParameter(inp,'theFiles','pickup') %Cell array containing paths to the input video files, "pickup" let the user choose
addParameter(inp,'UseBV',1) %Use BVz for aligmen. Disable this i
addParameter(inp,'BVz',[]) %Size of blood vessels [min diameter max diameter] in pixels.
% defaults is in the range range [0.6*opt.gSig,0.9*opt.gSig];
%Size of blood vessels [min diameter max diameter] in pixels.
addParameter(inp,'FinalAlignmentWithNeuronShapes',0) % Add an extra alignment iteration utilizing only neuron shapes after CaliAli
addParameter(inp,'FinalAlignmentWithNeuronShapes',0) % Add an extra alignment iteration utilizing only ne
%%
addParameter(inp,'dynamic_spatial',0) % not currently in use
addParameter(inp,'datename',0) % not currently in use
%% Internal variables
addParameter(inp,'Mask',[]) % Used internally
addParameter(inp,'T_Mask',[]) % Used internally
addParameter(inp,'NR_Mask',[]) % Used internally
addParameter(inp,'NR_Mask_n',[]) % Used internally
addParameter(inp,'F',[]) % Used internally
addParameter(inp,'T',[]) % Used internally
addParameter(inp,'shifts',[]) % Used internally
addParameter(inp,'shifts_n',[]) % Used internally
addParameter(inp,'BV_score',[]) % Used internally
addParameter(inp,'range',[]) % Used internally
addParameter(inp,'Cn_scale',[]) % Used internally
addParameter(inp,'date_v',[])
varargin=varargin{1, :};
if isstruct(varargin)
varargin = [fieldnames(varargin), struct2cell(varargin)]';
end

inp.KeepUnmatched = true;
parse(inp,varargin{:});
opt=inp.Results;

if isempty(opt.BVz)
opt.BVz=[0.6*opt.gSig,0.9*opt.gSig];
end


if strcmpi(opt.theFiles,"pickup")
opt.theFiles = uipickfiles('FilterSpec','*mc.h5');
end


if ~isempty(opt.theFiles)
[filepath,name]=fileparts(opt.theFiles{end});
opt.out=strcat(filepath,filesep,name,'_aligned','.h5');
opt.out_mat=strcat(filepath,filesep,name,'_aligned.mat');
else
opt.out=[];
opt.out_mat=[];
end
end
6 changes: 5 additions & 1 deletion Align_sessions/int_var.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
addParameter(inp,'sf',10,valid_v) %Frame rate. Defualt 10 fps
addParameter(inp,'n_enhanced',1) %MIN1PIE background substraciton. True is recommended. default True
addParameter(inp,'theFiles','pickup') %Cell array containing paths to the input video files, "pickup" let the user choose
addParameter(inp,'UseBV',1) %Cell array containing paths to the input video files, "pickup" let the user choose
addParameter(inp,'UseBV',1) %Use BVz for alignment. Disable this if you want to align sessions using only neuron
% shapes.
addParameter(inp,'BVz',[]) %Size of blood vessels [min diameter max diameter] in pixels.
% defaults is in the range range [0.6*opt.gSig,0.9*opt.gSig];
%Size of blood vessels [min diameter max diameter] in pixels.
addParameter(inp,'FinalAlignmentWithNeuronShapes',0) % Add an extra alignment iteration utilizing only neuron shapes after CaliAli
addParameter(inp,'Force_BVz',0) % Fore the use of BVz for alignment, even if BVz stability score is low.
%%
addParameter(inp,'dynamic_spatial',0) % not currently in use
addParameter(inp,'datename',0) % not currently in use
Expand Down
106 changes: 106 additions & 0 deletions Align_sessions/localHistMatch.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
function J = localHistMatch(Im, ref, win, patchOverlap, intensityThreshold)
% localHistMatch performs local histogram matching of an image with overlapping patches,
% ignoring regions below a certain intensity threshold.
%
% Inputs:
% Im - Input grayscale image (MxN matrix).
% ref - Reference grayscale image (MxN matrix).
% win - Window size [height, width] for local processing.
% patchOverlap - Overlap between patches [height, width].
% intensityThreshold - Minimum intensity value to include in processing.
%
% Output:
% J - Image after local histogram matching.

% Validate inputs
if nargin ~= 5
error('Five input arguments required: Im, ref, win, patchOverlap, and intensityThreshold.');
end

if ~ismatrix(Im) || ~ismatrix(ref)
error('Input images must be grayscale (2D matrices).');
end

if numel(win) ~= 2 || any(win <= 0)
error('Window size must be a vector with two positive integers.');
end

if numel(patchOverlap) ~= 2 || any(patchOverlap < 0)
error('Patch overlap must be a vector with two non-negative integers.');
end

if ~isscalar(intensityThreshold) || intensityThreshold < 0
error('Intensity threshold must be a non-negative scalar.');
end

% Convert images to grayscale if they are not already
if size(Im, 3) == 3
Im = rgb2gray(Im);
end
if size(ref, 3) == 3
ref = rgb2gray(ref);
end

% Ensure the reference image has the same size as the input image
[m, n] = size(Im);
[ref_m, ref_n] = size(ref);
if m ~= ref_m || n ~= ref_n
error('Input image and reference image must have the same dimensions.');
end

% Create an empty image to store the result
J = zeros(size(Im), 'like', Im);

% Determine the window size and overlap
windowHeight = win(1);
windowWidth = win(2);
overlapHeight = patchOverlap(1);
overlapWidth = patchOverlap(2);

% Compute the step size based on window size and overlap
stepY = windowHeight - overlapHeight;
stepX = windowWidth - overlapWidth;

% Create a mask to keep track of valid pixels
mask = false(size(Im));

% Process the image in overlapping local regions
for i = 1:stepY:m
for j = 1:stepX:n
% Define the window limits
rowRange = i:min(i+windowHeight-1, m);
colRange = j:min(j+windowWidth-1, n);

% Extract the local region from the input image
localRegion = Im(rowRange, colRange);
localMask = localRegion > intensityThreshold;

% Extract the local region from the reference image (same region)
refRegion = ref(rowRange, colRange);

% Apply mask to exclude low-intensity regions
if any(localMask(:))
% Perform histogram matching
matchedRegion = imhistmatch(localRegion, refRegion);
if max(matchedRegion,[],"all")>1
dummy=1;
end
% Apply the mask to the matched region
temp=Im(rowRange, colRange);

matchedRegion(~localMask) = temp(~localMask);

% Place the matched region back into the output image
J(rowRange, colRange) = matchedRegion;

% Update mask
mask(rowRange, colRange) = mask(rowRange, colRange) | localMask;
end
end
end

% Normalize the output image to account for overlapping regions
% J(mask) = J(mask) ./ (sum(mask(:)) / numel(J));

% Ensure the output image is in the same format as the input
end
Loading

0 comments on commit f37e9ff

Please sign in to comment.