Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 42 additions & 6 deletions src/dic_param.m
Original file line number Diff line number Diff line change
@@ -1,21 +1,57 @@
% STEP D, E, F: 2D-DIC, 3D Reconstruction, Deformation analysis

%% Subject and Trial Settings
subject_id = "S09"; % Subject identifier
phase_id = "loading"; % Phase identifier
material_id = 2; % Material identifier
nfcond_set = [5]; % Number of conditions
spddxlcond_set = [0.04, 0.08]; % Speed conditions

% Calibration settings
%% Calibration Settings
calib_folder_set = "2";
ref_trial_id = 5; % Reference trial number

% Reference trial number
ref_trial_id = 5;

% Frame settings
%% Frame Settings
idx_frame_start = 1;
idx_frame_end = 150;
frame_jump = 1;

% Visualization settings
%% Visualization Settings
showvisu = 0; % Boolean for visualization
debug_mode = 0; % Debug mode flag

%% DIC Global Constants
DIC.TRUE_FPS = 50;
DIC.LIMIT_GRAYSCALE = struct(...
'default', 100,...
'early_subjects', 70,...
'threshold', 8 ... % Subject numbers below this use early_subjects value
);

%% DIC Analysis Parameters
DIC.filtering = struct(...
'enabled', true...
);

DIC.ncorr = struct(...
'analysis_direction', 'regular',...
'subset_radius', struct(...
'tracking', 40,...
'matching', 60 ...
),...
'subset_spacing', 10,...
'cutoff', struct(...
'tracking', 1e-5,...
'matching', 1e-5 ...
),...
'solver', struct(...
'max_iterations', 100,...
'num_threads', 1 ...
),...
'strain_analysis', struct(...
'enabled', 1,...
'propagation', 'seed',...
'auto_ref_change', 1,...
'step_ref_change', 10 ...
) ...
);
90 changes: 90 additions & 0 deletions src/lib/dic_matching.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
function [matching_results] = dic_matching(prep_params)
% Get required parameters
base_parameters = prep_params.base_parameters;
step1_2_parameters = prep_params.step1_2_parameters;
cam_data = prep_params.cam_data;

% Define file paths
roifile = prep_params.roifile;

matchingfile = prep_params.matchingfile;

seedfile = prep_params.seedfile;

%% ROI and Seed initialization
% Draw ROI if needed
if ~exist(roifile, 'file')
draw_ref_roi(base_parameters);
end

% Perform matching if needed
if ~exist(matchingfile, 'file')
ncorr_matching2ref(cam_data.first_satur(:,:,1), prep_params, step1_2_parameters);
end

% Load matching results
matching = load(matchingfile);
refmask_REF = matching.reference_save(1).roi.mask;
refmask_trial = matching.current_save(1).roi.mask;
fprintf('--> STEP: ROI loaded and formatted\n');

% Handle seed points
if ~exist(seedfile, 'file')
draw_ref_seed(base_parameters, 'roi', refmask_REF);
end

% Load and map seed points
seed_point = load(seedfile);
ref_seed_point.pw = seed_point.seed_point;
ref_seed_point.sw = map_pixel2subset(ref_seed_point.pw, step1_2_parameters.spacing);

% Map coordinates
U_mapped = matching.data_dic_save.displacements(1).plot_u_ref_formatted/(step1_2_parameters.spacing + 1);
V_mapped = matching.data_dic_save.displacements(1).plot_v_ref_formatted/(step1_2_parameters.spacing + 1);

initial_seed_point_set1.sw = map_pointcoordinate(ref_seed_point.sw, {U_mapped, V_mapped});
initial_seed_point_set1.pw = map_subset2pixel(initial_seed_point_set1.sw, step1_2_parameters.spacing);

fprintf('--> STEP: SEED loaded and formatted\n');

%% Perform matching analysis
tic;
step1_2_parameters.initial_seed = initial_seed_point_set1.pw;

siz = size(cam_data.first);
input1 = cam_data.first_satur(:,:,1);
input2 = zeros(siz(1), siz(2), 2, 'uint8');
input2(:,:,1) = cam_data.second_satur(:,:,1);
input2(:,:,2) = cam_data.first_satur(:,:,1);

[h12, file_logic] = ncorr_dic_rewrited('cam_number', [cam_data.cam_1, cam_data.cam_2],...
'cam_data_ref', input1,...
'cam_data_cur', input2,...
'mask', refmask_trial,...
'automatic_process', base_parameters.automatic_process,...
'step_param', step1_2_parameters,...
'base_param', base_parameters);

% Get results for next step
refmask_trial_matched = h12.current(1).roi.mask;
U_mapped = h12.data_dic.displacements(1).plot_u_ref_formatted/(step1_2_parameters.spacing + 1);
V_mapped = h12.data_dic.displacements(1).plot_v_ref_formatted/(step1_2_parameters.spacing + 1);

initial_seed_point_set2.sw = map_pointcoordinate(initial_seed_point_set1.sw, {U_mapped, V_mapped});
initial_seed_point_set2.pw = map_subset2pixel(initial_seed_point_set2.sw, step1_2_parameters.spacing);

if ~file_logic
close(h12.handles_gui.figure);
end
clear('h12');

elapsedTime = toc;
fprintf("--> STEP: Ncorr matching 1-2 done in %1.1fs\n", elapsedTime);

%% Prepare output structure
matching_results = struct(...
'refmask_trial', refmask_trial,...
'refmask_trial_matched', refmask_trial_matched,...
'initial_seed_point_set1', initial_seed_point_set1,...
'initial_seed_point_set2', initial_seed_point_set2);
end
239 changes: 239 additions & 0 deletions src/lib/dic_preparation.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
function [prep_params] = dic_preparation(varargin)
%% Parse input arguments
p = inputParser;
p.addParameter('baseDataPath',[]);
p.addParameter('baseResultPath',[]);
p.addParameter('subject',[]);
p.addParameter('material',[]);
p.addParameter('trial',[]);
p.addParameter('stereopair',[]);
p.addParameter('phase',[]);
p.addParameter('jump',[]);
p.addParameter('idxstart_set',[]);
p.addParameter('idxend_set',[]);
p.addParameter('showvisu',0);
p.addParameter('savedata',1);
p.addParameter('reftrial_setmanual',[]);
p.addParameter('param_filt_im',[25 300]);
p.addParameter('automatic_process', true);

p.parse(varargin{:});
base_parameters = struct(...
'baseDataPath', p.Results.baseDataPath,...
'baseResultPath', p.Results.baseResultPath,...
'subject', p.Results.subject,...
'material', p.Results.material,...
'trial', p.Results.trial,...
'stereopair', p.Results.stereopair,...
'phase', p.Results.phase,...
'jump', p.Results.jump,...
'idxstart_set', p.Results.idxstart_set,...
'idxend_set', p.Results.idxend_set,...
'automatic_process', p.Results.automatic_process, ...
'reftrial_setmanual', p.Results.reftrial_setmanual, ...
'param_filt_im', p.Results.param_filt_im, ...
'savedata', p.Results.savedata, ...
'showvisu', p.Results.showvisu ...
);


%% Load DIC parameters
dic_param;

%% Get subject-specific grayscale limit
subject_number = str2double(cell2mat(regexp(base_parameters.subject, '\d+', 'match')));
if subject_number < DIC.LIMIT_GRAYSCALE.threshold
LIMIT_GRAYSCALE = DIC.LIMIT_GRAYSCALE.early_subjects;
else
LIMIT_GRAYSCALE = DIC.LIMIT_GRAYSCALE.default;
end

% Get DIC parameters
TRUE_FPS = DIC.TRUE_FPS;
im_filter_mode = DIC.filtering.enabled;

% Get Ncorr parameters
analysis_direction = DIC.ncorr.analysis_direction;
subset_radius_ncorr_tracking = DIC.ncorr.subset_radius.tracking;
subset_radius_ncorr_matching = DIC.ncorr.subset_radius.matching;
subset_spacing = DIC.ncorr.subset_spacing;
cutoff_tracking = DIC.ncorr.cutoff.tracking;
cutoff_matching = DIC.ncorr.cutoff.matching;
number_iteration_solver = DIC.ncorr.solver.max_iterations;
number_threads = DIC.ncorr.solver.num_threads;
high_strain_analysis = DIC.ncorr.strain_analysis.enabled;
seed_propagation = DIC.ncorr.strain_analysis.propagation;
auto_ref_change = DIC.ncorr.strain_analysis.auto_ref_change;
step_ref_change = DIC.ncorr.strain_analysis.step_ref_change;

%% Setup paths and load protocol
outputPath = fullfile(base_parameters.baseResultPath, base_parameters.subject, ...
base_parameters.material, base_parameters.trial, base_parameters.phase);
if ~exist(outputPath, 'dir')
mkdir(outputPath);
end

% load protocol
protocolPath = fullfile(fullfile(base_parameters.baseDataPath, "rawdata", ...
base_parameters.subject, "speckles", base_parameters.material, "protocol", sprintf('*.mat')));
S = dir(protocolPath);
if isempty(S)
error('Error: Protocol not found.');
end
p = load(fullfile(S.folder, S.name));
protocol = p.cond;

dircond = protocol.table(:,strcmp(protocol.titles,'dir'));
nfcond = cell2mat(protocol.table(:,strcmp(protocol.titles,'nf')));
spdcond = cell2mat(protocol.table(:,strcmp(protocol.titles,'spd')));
repcond = cell2mat(protocol.table(:,strcmp(protocol.titles,'rep')));

% reference trial determination
if (strcmp(base_parameters.phase,"loading") || nfcond(str2double(base_parameters.trial)) == 1)
reftrial = sprintf("%03d",find(nfcond == 1 & strcmp(dircond,"Ubnf"),1));
elseif strcmp(base_parameters.phase,"slide1") && nfcond(str2double(base_parameters.trial)) == 5
reftrial = sprintf("%03d",find(nfcond == 5 & strcmp(dircond,"Ubnf"),1));
else
error('Error: no ref trial assigned');
end

if ~isempty(base_parameters.reftrial_setmanual)
reftrial = base_parameters.reftrial_setmanual;
end

%% Read and process images
tic;
[cam_first_raw, cam_second_raw, cam_1, cam_2] = import_vid(base_parameters.baseDataPath,...
'subject', base_parameters.subject,...
'material', base_parameters.material,...
'trial', base_parameters.trial,...
'stereopair', base_parameters.stereopair,...
'phase', base_parameters.phase,...
'idxstart_set', base_parameters.idxstart_set,...
'idxend_set', base_parameters.idxend_set,...
'framejump', base_parameters.jump);
elapsedTime = toc;
fprintf("reading done in %1.1fs\n", elapsedTime);

% Process phase-specific data
if strcmp(base_parameters.phase, "slide1")
cam_first_raw = cam_first_raw(:,:,1:end/2+5);
cam_second_raw = cam_second_raw(:,:,1:end/2+5);
end

% Image saturation
cam_first_satur = satur(cam_first_raw, 'level', LIMIT_GRAYSCALE);
cam_second_satur = satur(cam_second_raw, 'level', LIMIT_GRAYSCALE);

% Image filtering
if im_filter_mode
[cam_first, gsboundaries] = filter_like_ben(cam_first_satur, 'paramfilt', base_parameters.param_filt_im);
cam_second = filter_like_ben(cam_second_satur, 'gsbound', gsboundaries, 'paramfilt', base_parameters.param_filt_im);
fprintf('--> STEP: filtering done\n');
else
cam_first = cam_first_raw;
cam_second = cam_second_raw;
fprintf('--> STEP: raw data used\n');
end

%% Create parameter structures for DIC analysis
step1_parameters = struct(...
'type', analysis_direction,...
'radius', subset_radius_ncorr_tracking,...
'spacing', subset_spacing,...
'cutoff_diffnorm', cutoff_tracking,...
'cutoff_iteration', number_iteration_solver,...
'total_threads', number_threads,...
'stepanalysis_params', struct(...
'enabled', high_strain_analysis,...
'type', seed_propagation,...
'auto', auto_ref_change,...
'step', step_ref_change));

step1_2_parameters = struct(...
'type', analysis_direction,...
'radius', subset_radius_ncorr_matching,...
'spacing', subset_spacing,...
'cutoff_diffnorm', cutoff_matching,...
'cutoff_iteration', number_iteration_solver,...
'total_threads', number_threads,...
'stepanalysis_params', struct(...
'enabled', high_strain_analysis,...
'type', seed_propagation,...
'auto', auto_ref_change,...
'step', step_ref_change));

%% Save frame information
idxframe = base_parameters.idxstart_set:base_parameters.jump:base_parameters.idxend_set;
actual_fps_meas = TRUE_FPS/base_parameters.jump;

savefileName = fullfile(outputPath, sprintf('dic_info_data_target_pair%d.mat', base_parameters.stereopair));
save(savefileName, 'actual_fps_meas', 'idxframe');

%% Prepare tracking configurations
tracking_configs = {
struct(...
'cam_number', cam_1,...
'ref_data', cam_first(:,:,1),...
'cur_data', cam_first(:,:,1:end),...
'step_number', 1 ...
), ...
struct(...
'cam_number', cam_2,...
'ref_data', cam_second(:,:,1),...
'cur_data', cam_second(:,:,2:end),...
'step_number', 2 ...
)
};

%% Prepare output structure
roifile = fullfile(base_parameters.baseResultPath, base_parameters.subject, ...
base_parameters.material, sprintf("REF_MASK_%s_%s_pair%s.mat", ...
reftrial, base_parameters.phase, base_parameters.stereopair+""));

matchingfile = fullfile(outputPath, ...
sprintf("MATCHING2%s_pair%s.mat", reftrial, base_parameters.stereopair+""));

seedfile = fullfile(base_parameters.baseResultPath, base_parameters.subject, ...
base_parameters.material, sprintf("REF_SEED_%s_%s_pair%s.mat", ...
reftrial, base_parameters.phase, base_parameters.stereopair+""));

prep_params = struct(...
'base_parameters', base_parameters,...
'step1_parameters', step1_parameters,...
'step1_2_parameters', step1_2_parameters,...
'outputPath', outputPath,...
'reftrial', reftrial,...
'cam_data', struct(...
'first_raw', cam_first_raw,...
'second_raw', cam_second_raw,...
'first', cam_first,...
'second', cam_second,...
'first_satur', cam_first_satur,...
'second_satur', cam_second_satur,...
'cam_1', cam_1,...
'cam_2', cam_2),...
'tracking_configs', tracking_configs,...
'LIMIT_GRAYSCALE', LIMIT_GRAYSCALE,...
'actual_fps_meas', actual_fps_meas,...
'idxframe', idxframe, ...
'roifile', roifile, ...
'matchingfile', matchingfile, ...
'seedfile', seedfile ...
);

% Print summary
fprintf("Trial information summary '%s' %s %s %s\n > Dir: %s\n > Force: %dN\n > Spd: %dmm/s\n > Rep: %d\n > REFtrial: '%s'\n > NbrFr: %d\n > Frame : %s\n > Actual FPS : %d\n",...
base_parameters.trial,...
base_parameters.phase,...
base_parameters.material,...
base_parameters.subject,...
dircond{str2double(base_parameters.trial)},...
nfcond(str2double(base_parameters.trial)),...
spdcond(str2double(base_parameters.trial)),...
repcond(str2double(base_parameters.trial)),...
reftrial,...
size(cam_first,3),...
mat2str(idxframe),...
actual_fps_meas);
end
Loading