-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
518ff90
commit 7e5b706
Showing
26 changed files
with
2,382 additions
and
0 deletions.
There are no files selected for viewing
118 changes: 118 additions & 0 deletions
118
Data Preparation/ORION/Modelnet/functions/binlist_to_hdf5.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
function binlist_to_hdf5(bins_list,h5_filename,h5_text_filename,chunk_size,run_on_cluster,write_just_this_chunk) | ||
%%% | ||
%%% In this function we assume the list is formatted as '%s %d %d %d' | ||
%%% where the first integer is ignored, the second is class label and the | ||
%%% 3rd one is the pose_label. | ||
%%% We put the pose-label in the file, eventhough sometimes it's not used; It's safe -- tested! | ||
%%% | ||
|
||
%-- Load the list | ||
[files,l1,l2,l3] = textread(bins_list,'%s %d %d %d'); | ||
N = numel(files); | ||
|
||
if(~exist('chunk_size','var')), chunk_size = 10000;end | ||
nchunks = ceil(N/chunk_size); | ||
|
||
%-- Create the target dir(s) if needed | ||
[pathstr,~,~] = fileparts(h5_filename); | ||
system(['wsl mkdir -p ' pathstr]); | ||
[pathstr,~,~] = fileparts(h5_text_filename); | ||
system(['wsl mkdir -p ' pathstr]); | ||
|
||
%-- See which chunks should we create | ||
if(exist('write_just_this_chunk','var') && any(write_just_this_chunk)) | ||
chunk_list = write_just_this_chunk; | ||
else | ||
chunk_list = 1 : nchunks; | ||
end | ||
|
||
%--- create the text file containing names of files (only if we should!) | ||
if(numel(chunk_list) == nchunks) | ||
create_the_text_file(h5_text_filename,h5_filename,nchunks) | ||
end | ||
|
||
|
||
%--- If we should submit jobs to cluster | ||
if(exist('run_on_cluster','var') && run_on_cluster) | ||
|
||
|
||
for the_chunk = chunk_list | ||
cmd = sprintf(['matlabD -nosplash -r "run ~/startup.m; '... | ||
'binlist_to_hdf5(''%s'',''%s'',''%s'',%d,0,%d); '... | ||
'exit"'],bins_list,h5_filename,h5_text_filename,chunk_size,the_chunk); | ||
|
||
temp_job_dir= [ getenv('HOME') '/temp_cluster_job' ]; | ||
[~,~,wait_file{the_chunk}] = cluster_submit_job('lmbtorque',cmd,temp_job_dir,6,'6G',0,'',3,0); | ||
pause(1); | ||
end | ||
|
||
return; | ||
end | ||
|
||
fprintf('Source: %s\nDestination1: %s\nDestination2: %s\n',bins_list,h5_filename,h5_text_filename); | ||
%--- Load the first bin to obtain the dimensions | ||
temp_v = load_binary_voxelgrid(files{1}); | ||
d1= size(temp_v,1); | ||
d2= size(temp_v,2); | ||
d3= size(temp_v,3); | ||
|
||
|
||
if(~exist('write_just_this_chunk','var')), | ||
write_just_this_chunk = 0; | ||
end | ||
|
||
for c = chunk_list | ||
fprintf('Chunk: %d/%d\n',c,nchunks); | ||
|
||
written_sofar = (c-1)*chunk_size; | ||
this_chunk_size = min(chunk_size,N-written_sofar); | ||
ind1 = written_sofar+1; | ||
ind2 = ind1+this_chunk_size-1; | ||
|
||
%--- Load bins one by one and keep in memory | ||
disp('Loading bin files...'); | ||
Data = zeros(d1,d2,d3,1,this_chunk_size); | ||
tic | ||
for i = 1 : this_chunk_size %I have tried parfor here previously. It makes it slower!! | ||
data = load_binary_voxelgrid(files{ind1+i-1}); | ||
Data(:,:,:,1,i) = data; | ||
if(~mod(i,50)), fprintf('%d ',i);end | ||
end | ||
fprintf('\n'); | ||
toc | ||
Data = uint8(Data); | ||
|
||
|
||
%-- Write the hdf5 file(s) | ||
disp('Writing the hdf5 file(s)...'); | ||
|
||
%- get the appropriate filename for this chunk | ||
filename = get_chunk_filename(c,h5_filename); | ||
|
||
if(exist(filename,'file')),delete(filename);end | ||
|
||
h5create(filename,'/data',[d3 d2 d1 1 this_chunk_size],'Datatype','uint8'); | ||
h5create(filename,'/label',[1 this_chunk_size]); | ||
h5create(filename,'/label_pose',[1 this_chunk_size]) | ||
h5write(filename,'/data',Data); | ||
h5write(filename,'/label',l2(ind1:ind2)'); | ||
h5write(filename,'/label_pose',l3(ind1:ind2)'); | ||
|
||
end | ||
end | ||
|
||
function filename = get_chunk_filename(chunk,h5_filename) | ||
if chunk == 1 | ||
filename = h5_filename; | ||
else | ||
filename = sprintf('%s.%04d',h5_filename,chunk); | ||
end | ||
end | ||
|
||
function create_the_text_file(textfilename,h5filename,nchunks) | ||
fp = fopen(textfilename,'wt'); | ||
for c = 1 : nchunks | ||
fprintf(fp,'%s\n',get_chunk_filename(c,h5filename)); | ||
end | ||
fclose(fp); | ||
end |
7 changes: 7 additions & 0 deletions
7
Data Preparation/ORION/Modelnet/functions/load_binary_voxelgrid.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
function v = load_binary_voxelgrid(filename) | ||
|
||
fp = fopen(filename,'rb'); | ||
sz = fread(fp,3,'uint16'); | ||
v = zeros(sz'); | ||
v(:) = fread(fp,prod(sz),'uint8'); | ||
fclose(fp); |
57 changes: 57 additions & 0 deletions
57
Data Preparation/ORION/Modelnet/functions/modelnet_add_labels_to_list.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
function modelnet_add_labels_to_list(source_list_file,dest_list_file,rotation_start_index,Pose_file) | ||
|
||
list = textread(source_list_file,'%s'); | ||
Pose=importdata(Pose_file,'\t'); | ||
%parfor | ||
parfor i = 1 : numel(list) | ||
% extracts from folder classname e.g bathtub and from the filename it | ||
% extracts the index of the rotation e.g 1 | ||
[class_name,rotation] = modelnet_extract_classname_and_rot_from_filename(list{i}); | ||
% rotation-rotation_start_index to bring rotation index in [0, maxrot-1] | ||
% return the class label [0, maxclass-1] anc the pose label | ||
% if all_singlerots_to_zero=1 then fo all the classes with only 1 | ||
% orientation it gives the the label 0 (independently from the class) | ||
% otherwise it gives an increasing number based on actual orientation, | ||
% class number and previus classes orientation labelling | ||
[class_label,pose_label] = modelnet_generate_class_and_pose_labels(class_name,rotation-rotation_start_index,Pose); | ||
list{i} = sprintf('%s %d %d %d' ,list{i},1,class_label,pose_label); | ||
end | ||
|
||
%--- write the modified list to the destination file | ||
fp = fopen(dest_list_file,'wt'); | ||
fprintf(fp,'%s\n',list{:}); | ||
fclose(fp); | ||
end | ||
|
||
|
||
function [class_name,rotation] = modelnet_extract_classname_and_rot_from_filename(filename) | ||
|
||
s = strsplit(filename,{'.','/'}); | ||
class_name = s{end-4}; | ||
r = strsplit(s{end-1},'_'); | ||
rotation = str2double(r(end)); | ||
end | ||
|
||
function [class_label,pose_label] = modelnet_generate_class_and_pose_labels(class_name,rotation,Pose) | ||
|
||
%%% Note: Class Label and Pose Label both start from 0. | ||
classes=Pose.textdata'; | ||
nrot=Pose.data'; | ||
|
||
%--- Find the Class Label | ||
[valid_class,class_label] = ismember(class_name,classes); | ||
if(~valid_class) | ||
class_label = -1; | ||
pose_label = -1; | ||
return; | ||
end | ||
class_label = class_label - 1; %to start from 0 | ||
|
||
%--- Find the rotation label | ||
cr = cumsum(nrot); | ||
cr = circshift(cr,[0,1]); | ||
cr(1) = 0; | ||
pose_label = cr(class_label+1) + mod(rotation,nrot(class_label+1)); | ||
|
||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
addpath(genpath('polygon2voxel/')); | ||
addpath(genpath('functions/')); | ||
|
||
modelnet10_classes = {'bathtub','bed','chair','desk','dresser','monitor','night_stand','sofa','table','toilet'}; | ||
modelnet40_classes = {'airplane','bathtub','bed','bench','bookshelf','bottle','bowl','car',... | ||
'chair','cone','cup','curtain','desk','door','dresser','flower_pot','glass_box',... | ||
'guitar','keyboard','lamp','laptop','mantel','monitor','night_stand','person',... | ||
'piano','plant','radio','range_hood','sink','sofa','stairs','stool','table',... | ||
'tent','toilet','tv_stand','vase','wardrobe','xbox'}; | ||
|
||
|
||
%-------------------- Modelnet Data Preparation --------------- | ||
%---------------------------------------------------------------- | ||
%---------------------------------------------------------------- | ||
off_path='../../datasets/ModelNet40'; | ||
mat_path='../../datasets/ModelNet40_voxelized_mat'; | ||
bin_path = '../../datasets/ModelNet40_bin_from_mat/'; | ||
|
||
%--- convert original .off to .mat files------ | ||
%----------------(voxel grids)---------------- | ||
%--------------------------------------------- | ||
volume_size = 24; | ||
pad_size = 3; | ||
angle_inc = 15; | ||
modelnet_off2mat(off_path,mat_path,modelnet40_classes,volume_size,pad_size,angle_inc); | ||
|
||
%--------------------------------------------- | ||
%---------- convert .mat to .bin files ------- | ||
%--------------------------------------------- | ||
D = 3; %padding on each side. | ||
%We convert 30 to 36, such that after cropping we get 32, similar to what voxnet does | ||
modelnet_mat2bin(D,mat_path,bin_path, angle_inc); | ||
|
||
%--------------------------------------------- | ||
%--------- convert bin to HDF5 chunks -------- | ||
%--------------------------------------------- | ||
Pose_plan='poseplan_MN40_24'; | ||
modelnet_binlist2hdf5(bin_path,Pose_plan,angle_inc); | ||
%--------------------------------------------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
function modelnet_binlist2hdf5(DestinationFolder,Pose_plan,angle_inc) | ||
|
||
Pose_file=['../poseplans/' Pose_plan '.txt']; | ||
if ~exist(strcat(DestinationFolder,Pose_plan,'/'), 'dir') | ||
mkdir(strcat(DestinationFolder,Pose_plan,'/')); | ||
end | ||
copyfile(Pose_file,strcat(DestinationFolder,Pose_plan,'/')); | ||
|
||
%% ---- Create the lists | ||
rotation_start_index = 1; %this is the original Shapenet convention | ||
lists_dir = sprintf('%s/%s',DestinationFolder,Pose_plan); | ||
alllist_file = sprintf('%s/all.txt',lists_dir); | ||
|
||
system(sprintf('wsl find %s -path "*/%s/*" -iname ''*.%s'' | wsl sort -V > %s', DestinationFolder,num2str(angle_inc),'bin',alllist_file)); | ||
% | ||
modelnet_add_labels_to_list(alllist_file,alllist_file,rotation_start_index,Pose_file); | ||
|
||
% preparing training validation test lists | ||
for set = {'train','test','validation'} | ||
dest_filename = sprintf('%s/%s.txt',lists_dir,set{1}); | ||
system(sprintf('wsl grep ''/%s/'' %s > %s',set{1},alllist_file,dest_filename)); | ||
end | ||
|
||
%% --- Create some special HDF5 datasets | ||
binlist_to_hdf5([lists_dir '/train.txt'],[DestinationFolder '/' Pose_plan '/hdf5/train/train.hdf5'],[DestinationFolder '/' Pose_plan '/hdf5/train/train.txt'],1000); | ||
binlist_to_hdf5([lists_dir '/validation.txt'],[DestinationFolder '/' Pose_plan '/hdf5/validation/validation.hdf5'],[DestinationFolder '/' Pose_plan '/hdf5/validation/validation.txt'],1000); | ||
binlist_to_hdf5([lists_dir '/test.txt'],[DestinationFolder '/' Pose_plan '/hdf5/test/test.hdf5'],[DestinationFolder '/' Pose_plan '/hdf5/test/test.txt'],1000); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
function modelnet_mat2bin(D,SourceFolder,DestinationFolder, angle_inc) | ||
%%% This function loads the files in the folders one by one, and saves the bin | ||
%%% versions to a similar subdir in the destination (tries to create it). | ||
%%% We go folder by folder, so that Matlab doesn't need to call the SLOW | ||
%%% fileparts function to find the folder names | ||
|
||
%--- Generate folders list | ||
temp_folders_list_file = 'temp_modelnet_folders.txt'; | ||
disp('Generating folders list...'); | ||
system(sprintf('wsl find %s -mindepth 3 -type d -path "*/%s/*"> %s',SourceFolder,num2str(angle_inc),temp_folders_list_file)); | ||
|
||
%--- Load the folders list | ||
folders_list = textread(temp_folders_list_file,'%s'); | ||
|
||
%--- Loop on the folders | ||
disp('Converting files...'); | ||
tic; | ||
for d = 1 : numel(folders_list) | ||
d | ||
folder = folders_list{d}; | ||
|
||
%--- Make the destination subfolder | ||
relative_folder = folder(length(SourceFolder)+2:end); | ||
system(sprintf('wsl mkdir %s/classes/%s -p',DestinationFolder,relative_folder)); | ||
|
||
%--- Get the list of files in each folder | ||
files_list = dir(sprintf('%s/*mat',folder)); | ||
|
||
%--- Loop on file names | ||
parfor f = 1 : numel(files_list) | ||
|
||
filename = [files_list(f).name]; | ||
fullfilename = [SourceFolder '/' relative_folder '/' filename]; | ||
|
||
%- Load the Mat file | ||
v = load(fullfilename); | ||
v = v.instance; | ||
|
||
%-- padding | ||
avoxel = zeros(size(v)+2*D); | ||
avoxel(1+D:end-D,1+D:end-D,1+D:end-D) = v; | ||
v = avoxel; | ||
|
||
%- Generate the bin filename | ||
dest_filename = [DestinationFolder '/classes/' relative_folder '/' filename(1:end-3) 'bin']; | ||
|
||
%- Save the bin | ||
fp = fopen(dest_filename,'w'); | ||
fwrite(fp,uint16(size(v)),'uint16'); | ||
fwrite(fp,uint8(v),'uint8'); | ||
fclose(fp); | ||
|
||
end | ||
end | ||
|
||
disp('Done'); | ||
toc | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
function modelnet_off2mat(off_path, data_path, classes, volume_size, pad_size, angle_inc) | ||
% Put the mesh object in a volume grid and save the volumetric | ||
% represenation file. | ||
% This is the input volumetric data for 3D ShapeNets. | ||
% off_path: root off data folder | ||
% data_path: destination volumetric data folder | ||
|
||
phases = {'train', 'test', 'validation'}; | ||
|
||
for c = 1 : length(classes) | ||
fprintf('writing the %s category\n', classes{c}); | ||
category_path = [off_path '/' classes{c}]; | ||
dest_path = [data_path '/' classes{c} '/' num2str(angle_inc)]; | ||
if ~exist(dest_path, 'dir') | ||
mkdir(dest_path); | ||
end | ||
% for train, test, validation phases | ||
for t = 1 : numel(phases) | ||
phase = phases{t}; | ||
off_list = [category_path '/' phase]; | ||
dest_tsdf_path = [dest_path '/' phase]; | ||
if ~exist(dest_tsdf_path, 'dir') | ||
mkdir(dest_tsdf_path); | ||
end | ||
files = dir(off_list); | ||
for i = 1 : length(files) | ||
if strcmp(files(i).name, '.') || strcmp(files(i).name, '..') || files(i).isdir == 1 || ~strcmp(files(i).name(end-2:end), 'off') | ||
continue; | ||
end | ||
|
||
filename = [off_list '/' files(i).name]; | ||
for viewpoint = 1 : 360/angle_inc | ||
destname = [dest_tsdf_path '/' files(i).name(1:end-4) '_' num2str(viewpoint) '.mat']; | ||
off_data = off_loader(filename, (viewpoint-1)*angle_inc); | ||
instance = polygon2voxel(off_data, [volume_size, volume_size, volume_size], 'auto'); | ||
instance = padarray(instance, [pad_size, pad_size, pad_size]); | ||
instance = int8(instance); | ||
save(destname, 'instance'); | ||
end | ||
end | ||
end | ||
end | ||
|
||
function offobj = off_loader(filename, theta) | ||
|
||
offobj = struct(); | ||
fid = fopen(filename, 'rb'); | ||
OFF_sign = fscanf(fid, '%c', 3); | ||
assert(strcmp(OFF_sign, 'OFF') == 1); | ||
|
||
info = fscanf(fid, '%d', 3); | ||
offobj.vertices = reshape(fscanf(fid, '%f', info(1)*3), 3, info(1))'; | ||
offobj.faces = reshape(fscanf(fid, '%d', info(2)*4), 4, info(2))'; | ||
|
||
% do some translation and rotation | ||
center = (max(offobj.vertices) + min(offobj.vertices)) / 2; | ||
offobj.vertices = bsxfun(@minus, offobj.vertices, center); | ||
|
||
% and rotation | ||
theta = theta * pi / 180; | ||
R = [cos(theta), -sin(theta), 0; | ||
sin(theta), cos(theta) , 0; | ||
0 , 0 , 1]; | ||
|
||
offobj.vertices = offobj.vertices * R; | ||
|
||
% These vertices to define faces should be offset by one to follow the matlab convention. | ||
offobj.faces = offobj.faces(:,2:end) + 1; | ||
|
||
fclose(fid); |
Oops, something went wrong.