Skip to content

Commit

Permalink
code edits to improve plotting functions #3 and reduce amount of user…
Browse files Browse the repository at this point in the history
… input needed in config file
  • Loading branch information
Swathi Sheshadri authored and Swathi Sheshadri committed Dec 10, 2019
1 parent abc5e95 commit 8a8a593
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 78 deletions.
Binary file modified .DS_Store
Binary file not shown.
Binary file modified Codes/.DS_Store
Binary file not shown.
3 changes: 0 additions & 3 deletions Codes/core_functions/reconstruct_3D.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@
end

%% 3D reconstruction using 2D coordinates tracked from every camera with
% coords3dall = nan(nframes,3*nfeatures); %one-shot 3D reconstruction
% coords3dbp = nan(nframes,3*nfeatures); %3D reconstructed from best pair
% coords3davg = nan(nframes,3*nfeatures); %averaging 3D reconstructions over pairs

coords3d = nan(nframes,3*nfeatures,length(modes_3drecon));

Expand Down
Binary file added Codes/helper_functions/.DS_Store
Binary file not shown.
112 changes: 82 additions & 30 deletions Codes/helper_functions/make_illustrative_movie.m
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
% Compute 3D data first before running this code for your experiment
% This function plots 3D reconstruction data alongside 2D tracking performed from all cameras
% In addition this function makes a movie of the same
%
% Before running this function
% Video files must be present at [exp_path '/' exp_name '/Videos/']
%
% Copyright (c) 2019 Swathi Sheshadri
% German Primate Center
Expand All @@ -20,36 +17,53 @@
close all
clc

%Take initialized values from config file
template_config_file %call your config file here
%%Take initialized values from config file
testing_config_file %call your config file here

load([exp_path '/' exp_name '/Data3d/Data3d.mat'],'coords3dall')
load([exp_path '/' exp_name '/Data3d/Data3d.mat'],'coords3d')
coords3dall = coords3d;

%Code to visualize 2d videos with 3d reconstruction results
figure('units','normalized','outerposition',[0 0 1 1])
figure('units','normalized','outerposition',[0 0 1 0.5])
colorclass = colormap(jet); %jet is default in DLC to-date
color_map_self=colorclass(1:nfeatures:64,:);
color_map_self=colorclass(ceil(linspace(1,64,nfeatures)),:);

%Place your DLC labelled video files in the project under Videos folder

v = dir([exp_path '/' exp_name '/Videos/*.mp4']); %Place your DLC labelled video files at this location
cam = cell(ncams,1);
for icams = 1:ncams
cam{icams,1} = VideoReader([v(icams,1).folder '/' v(icams,1).name]);

%path to the videos you want to visualize next to 3D tracked data
tracked_videos = [{'Fullpath/Video1.mp4';};...
{'Fullpath/Video2.mp4';};...
{'Fullpath/Video3.mp4';}];

%path 2D tracked csv files of the videos provided above
path_to_csv = [{'Fullpath/csvfileofVideo1.csv'};... %provide csv file order should
{'Fullpath/csvfileofVideo2.csv'};... %correspond to the movie file order
{'Fullpath/csvfileofVideo3.csv'};];

ncams_to_display = size(tracked_videos,1);
cam = cell(ncams_to_display ,1);
DataAll = nan(nframes,nfeatures*2,ncams_to_display ) ;

for icams = 1:ncams_to_display

if usingdlc
[data2d,data2dllh,flag_mis] = load_dlcdata(path_to_csv{icams},nframes,nfeatures,flag_mis);
else
[data2d,flag_mis] = load_otherdata(path_to_csv{icams},nframes,nfeatures,flag_mis);
end
DataAll(:,:,icams) = data2d;
cam{icams,1} = VideoReader([tracked_videos{icams,1}]);
end

%to make video
vidfile = VideoWriter([exp_path '/' exp_name '/Videos/' exp_name '2D_3Dmovie.mp4'],'MPEG-4');
if ~exist([exp_path '/' exp_name '/Videos/'],'dir')
mkdir([exp_path '/' exp_name '/Videos/'])
end
vidfile = VideoWriter([exp_path '/' exp_name '/Videos/' exp_name '2D_3Dmovie.avi']);
vidfile.FrameRate = fps;
open(vidfile)

if ~mod(size(cam,1),2)
subplot_size = size(cam,1);
else
subplot_size = size(cam,1)+1;
end

subplot_cols = ceil(subplot_size/2);
subplot_cols = size(cam,1)+1;

%setting maximum and minimum of axis of visualization
xvals = coords3dall(:,1:3:nfeatures*3);
Expand All @@ -63,26 +77,25 @@
zmax = max(zvals(:));
zmin = min(zvals(:));



for i =1:1:size(coords3dall,1)
temp = reshape(coords3dall(i,:),3,nfeatures);
subplot(2,subplot_cols,1)
scatter3(temp(1,:),temp(2,:),temp(3,:),250*ones(1,nfeatures),color_map_self(1:nfeatures,:),'filled');
subplot(1,subplot_cols,1)
scatter3(temp(1,:),temp(2,:),temp(3,:),50*ones(1,nfeatures),color_map_self(1:nfeatures,:),'filled');
hold on
for l = 1:size(drawline,1)
pts = [temp(:,drawline(l,1))'; temp(:,drawline(l,2))']; %line btw elbow and shoulder
line(pts(:,1), pts(:,2), pts(:,3),'color','k','linewidth',1.5)
end
hold off
%view to be set to suit the object being tracked
set(gca,'xtick',[],'ytick',[],'ztick',[],'view',[-10.0500 30.6124],'xlim',[xmin xmax],'ylim',[ymin ymax],'zlim',[zmin zmax],'Zdir', 'reverse') %change view and axis limits to fit your data


set(gca,'xtick',[],'ytick',[],'ztick',[],'view',[140.4073 -71.3356],'xlim',[-400 300],'ylim',[-300 300],'zlim',[300 800])

for n = 1:size(cam,1)
subplot(2,subplot_cols,n+1)
subplot(1,subplot_cols,n+1)
b = read(cam{n,1}, i);
imshow(b)
hold on
scatter(DataAll(i,1:2:2*nfeatures,n),DataAll(i,2:2:2*nfeatures,n),100*ones(1,nfeatures),color_map_self(1:nfeatures,:),'filled');
drawnow
end
set(gcf, 'color', 'white')
Expand All @@ -91,4 +104,43 @@

end

close(vidfile)
close(vidfile)

%A bit of code modularization & check for pose3d appropriate data
%Loading DLC 2D tracked data
function [data2d,data2dllh,flag_mis] = load_dlcdata(fullfilename,nframes,nfeatures,flag_mis)
data2d = importdata(fullfilename);
if isstruct(data2d) %case when excel contains column or row headers
data2d = data2d.data;
end
data2d = data2d(:,2:end);
data2dllh = data2d(:,3:3:end);
data2d(:,3:3:end) = [];

if nframes~= size(data2d,1)
flag_mis = 1;
end

if nfeatures*2 ~= size(data2d,2)
flag_mis = 1;
end

end

%loaded 2D tracked data from other software
function [data2d,flag_mis] = load_otherdata(fullfilename,nframes,nfeatures,flag_mis)
data2d = importdata(fullfilename);

if isstruct(data2d) %case when excel contains column or row headers
data2d = data2d.data;
end

if nframes~= size(data2d,1)
flag_mis = 1;
end

if nfeatures*2 ~= size(data2d,2)
flag_mis = 1;
end

end
59 changes: 30 additions & 29 deletions Codes/helper_functions/simple_3Ddata_plotter.m
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,7 @@
%% Vizualizing Rubik's Cube corners in 3D
%looping over time to plot cube reconstruction over different time points

if have2Dtrackedvideos == 1

%Load your DLC labelled video file
cam{1,1} = VideoReader(path_to_2Dtracked_video);

if color_bw
movie1 = zeros(cam{1,1}.Height,cam{1,1}.Width,3,length(1:nskip:size(coords3d,1)),'uint8');
else
movie1 = zeros(cam{1,1}.Height,cam{1,1}.Width,1,length(1:nskip:size(coords3d,1)),'uint8');
end
if have2Dtrackedvideos

disp('Loading your video data. This could take awhile...')
disp('Please consider increasing nskip value on config file if the visualization takes too long')
Expand All @@ -72,37 +63,42 @@
k = k+1;
end

else %when you have 2D tracked images
elseif have2Dtrackedimages %when you have 2D tracked images

files = dir([path2Dtrackedimages_folder '/*' format_of_images]);
if isempty(files)
flag_mis = 1;
uiwait(msgbox(sprintf('No 2D tracked images found at the location indicated by config file'),'Problem detected'))
return
end
temp_info = imfinfo([files(1).folder '/' files(1).name]);
if color_bw
movie1 = zeros(temp_info.Height,temp_info.Width,3,length(1:nskip:nframes),'uint8');
else
movie1 = zeros(temp_info.Height,temp_info.Width,1,length(1:nskip:nframes),'uint8');
end
k=1;
for t =1:nskip:length(files)
movie1(:,:,:,k) = imread([files(t).folder '/' files(t).name]);
k = k+1;
end


end



figure1 = figure('units','normalized','OuterPosition',[0.044 0.206 0.4 0.4]);
colorclass = colormap(jet); %jet is default in DLC
color_map_self=colorclass(ceil(linspace(1,64,nfeatures)),:);
if have2Dtrackedvideos || have2Dtrackedimages
figure1 = figure('units','normalized','OuterPosition',[0.044 0.206 0.4 0.4]);
colorclass = colormap(jet); %jet is default in DLC
color_map_self=colorclass(ceil(linspace(1,64,nfeatures)),:);

% Create axes for 3D reconstructed data
ha(1) = axes('Parent',figure1,'Position',[0.08 0.1 0.4 0.8]);

% Create axes for 3D reconstructed data
ha(1) = axes('Parent',figure1,'Position',[0.08 0.1 0.4 0.8]);
% Create axes for camera 2 data
ha(2) = axes('Parent',figure1,'Position',[0.55 0.1 0.4 0.8]);

% Create axes for camera 2 data
ha(2) = axes('Parent',figure1,'Position',[0.55 0.1 0.4 0.8]);
else
figure1 =figure('units','normalized','OuterPosition',[0.044 0.206 0.5 0.8]);
colorclass = colormap(jet); %jet is default in DLC
color_map_self=colorclass(ceil(linspace(1,64,nfeatures)),:);
ha(1) = axes('Parent',figure1,'Position',[0.1 0.1 0.8 0.8]);
end

tic
k = 1;
Expand All @@ -118,22 +114,26 @@
end
end
hold off
set(ha(1),'view',[-127.1,21.8],'xlim',[xmin xmax],'ylim',[ymin ymax],'zlim',[zmin zmax],'Zdir', 'reverse','Ydir', 'reverse')
set(ha(1),'view',[-127.1,21.8],'Zdir', 'reverse','Ydir', 'reverse')
title(sprintf(['3D reconstruction of features from ' num2str(ncams) ' cameras']))

%view to be set to suit the object being tracked
%the view is hardcoded here to suit the demo experiment (try different
%views to suit your data)
set(ha(1),'xtick',[],'ytick',[],'ztick',[],'xlim',[xmin xmax],'ylim',[ymin ymax],'zlim',[zmin zmax]) %change view and axis limits to suit your data

imagesc(movie1(:,:,:,k),'Parent', ha(2))
set(ha(2),'xtick',[],'ytick',[],'ztick',[])
if have2Dtrackedvideos || have2Dtrackedimages
imagesc(movie1(:,:,:,k),'Parent', ha(2))
hold on
scatter(DataAll(t,1:2:2*nfeatures,ncams),DataAll(t,2:2:2*nfeatures,ncams),250*ones(1,nfeatures),color_map_self(1:nfeatures,:),'filled','Parent', ha(2));
set(ha(2),'xtick',[],'ytick',[],'ztick',[])
end
drawnow

if have2Dtrackedvideos == 1
pause(nskip/fps)
pause(nskip/cam{1,1}.Framerate)
else
pause(0.05)
pause(0.1)
end

if toc > 60 %after every 60 seconds prompts user to check if she/he wants to stop watching movie
Expand Down Expand Up @@ -199,6 +199,7 @@
avgerrorall = nanmean(temperror(:));
stderrorall = nanstd(temperror(:));
disp(['Average error (mm) for reconstruction with mode ' modes_3drecon{imodes} ':' num2str(avgerrorall) ' ' char(177) ' ' num2str(stderrorall)])
disp('Error values corresponding to individual time-points and line-segments on the skeleton available in the workspace variable errorinrecond(timeXlinesegmentsXmodes_of_3Dreconstruction)')

end

Expand Down
Loading

0 comments on commit 8a8a593

Please sign in to comment.