-
Notifications
You must be signed in to change notification settings - Fork 0
/
reconstruct_body.m
131 lines (123 loc) · 5.07 KB
/
reconstruct_body.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
function [recon, angle] = reconstruct_body(init, frames,plot_flag)
%% reconstruct_body: reconstructs the fly body in the 3D plan and uses it to determine the heading of the fly
% Faster reconstruction using a predefined smaller volume
% Uses PCA for finding the fly heading
% OUPUT:
% ReconstructionData_space: The reconstruction data in metric units
% ReconstructionData_Voxel: The reconstruction in voxel coordinates
% load and analyze video
% determines changes in heading and the orthogonal system for each
% reconstruction
if plot_flag
f1_body_plot=figure;
end
maskdir = init.folders.mask;
crop_reigon = init.data.crop;
img_sz = init.data.image_size;
DLt_Coef = init.data.DLT;
load(init.paths.volume, 'Rec_Cord')
load(init.paths.z_axis, 'z_axis')
recondir = fullfile(init.folders.root, 'reconstruction');
mkdir(recondir)
mask_path = maskReader_image(maskdir);
image_type = '.png';
MOV = cell(3,1);
tic
sI = frames(1);
n_frame = length(frames);
body_angle_all=zeros(1,length(frames));
for n = 1:n_frame
if ~mod(frames(n),10) || (frames(n) == frames(1)) || (frames(n) == frames(end))
disp(frames(n))
end
recon.frame = frames(n);
% Load the tether masks for each view
fI = num2str(frames(n));
for f = 1:3
Icrop = imread([mask_path(f).body fI image_type]); % read mask image
MOV{f} = pad_image(Icrop, crop_reigon{f}, img_sz{f}); % pad so mask matches full image size
end
% Recontruct the body from all 3 views
coordinate_fly = reconstruct_from_images(MOV, DLt_Coef, Rec_Cord, false);
recon.body_xyz = coordinate_fly;
% fit 3D line to fly
body_vector = pca(coordinate_fly); % sed to find the fly heading
body_vector = body_vector(:,1); % take the strongest component
body_vector = body_vector/norm(body_vector);
recon.body_vector = body_vector; % checks if the body vector has flipped from one frame to the next
if (frames(n) > sI) && ( dot(recon.body_vector, recon_prev.body_vector) < 0 )
recon.body_vector = -recon.body_vector;
end
if frames(n)==sI %determines if the first body vector is in the right direction (from abdomen to head)
recon.body_vector=recon.body_vector*sign(dot(z_axis,body_vector)); %makes sure the body vector is in the +ve z-axis
f1_body=figure;
scatter3(coordinate_fly(:,1),coordinate_fly(:,2),coordinate_fly(:,3))
hold on
body_center=mean(coordinate_fly);
body_vector_red=recon.body_vector/200;
plot3([body_center(1) body_center(1)+body_vector_red(1)],...
[body_center(2) body_center(2)+body_vector_red(2)]...
,[body_center(3) body_center(3)+body_vector_red(3)],'k')
flip_axis=input('Flip body-axis y/n? ','s');
switch flip_axis
case 'y'
recon.body_vector=-recon.body_vector;
case 'n'
%Do nothing
end
close(f1_body)
clear body_center body_vector_red
end
% y-axis and x-axis calculation + save axes into a structure
x_axis = cross(recon.body_vector, z_axis);
x_axis = x_axis / norm(x_axis);
y_axis = cross(z_axis,x_axis);
recon.x_axis = x_axis;
recon.y_axis = y_axis;
recon.z_axis = z_axis;
% Calculate angle of the fly
if frames(n) > sI
angle = atan2(norm(cross(recon_init.x_axis, recon.x_axis)),...
dot(recon_init.x_axis, recon.x_axis));
else %initialize zero position of the fly as the zero yaw angle
angle = 0;
recon_init = recon;
end
recon.body_angle = angle;
body_angle_all(n)=angle;
recon_prev = recon;
%% Plot
if plot_flag
scatter3(coordinate_fly(:,1),coordinate_fly(:,2),coordinate_fly(:,3))
hold on
body_center=mean(coordinate_fly);
body_vector_red=recon.body_vector/200;
x_axis_red=x_axis/200;
y_axis_red=y_axis/200;
z_axis_red=z_axis/200;
plot3([body_center(1) body_center(1)+body_vector_red(1)],...
[body_center(2) body_center(2)+body_vector_red(2)]...
,[body_center(3) body_center(3)+body_vector_red(3)],'k')
plot3([body_center(1) body_center(1)+x_axis_red(1)],...
[body_center(2) body_center(2)+x_axis_red(2)]...
,[body_center(3) body_center(3)+x_axis_red(3)],'r')
plot3([body_center(1) body_center(1)+y_axis_red(1)],...
[body_center(2) body_center(2)+y_axis_red(2)]...
,[body_center(3) body_center(3)+y_axis_red(3)],'b')
plot3([body_center(1) body_center(1)+z_axis_red(1)],...
[body_center(2) body_center(2)+z_axis_red(2)]...
,[body_center(3) body_center(3)+z_axis_red(3)],'g')
end
%% Save
savepath = fullfile(recondir, ['frame_' fI '.mat']);
save(savepath, '-struct', 'recon')
end
if plot_flag
close(f1_body_plot)
end
toc
angle_dir=fullfile(init.folders.root, 'body_angle_all');
mkdir(angle_dir)
angle_savepath=fullfile(angle_dir, 'BodyAngle.mat');
save(angle_savepath, '-struct', 'body_angle_all')
end