PDA

View Full Version : A complete/concise m-file to read VICON .C3D files



Alan R Morris
10-22-1998, 01:18 AM
Dr. Kim and interested BIOMCH-L readers,

I have written an m-file that reads and writes all of the data contained
in a VICON C3D file that contains the following:

- header information
- parameter information
- data records (video and analog)

N.B. VICON V370 version 2.5 wrote marker records in no particular order
(ie. not in the order specified by the user!). The following program
writes all of the parameter information to a structure. This includes the
following which is quite important to correctly using the data:

- video units
- frequency
- analog scale and offset
- labels for both video and analog records in the order that data was
stored
- force plate location and type
- analog sampling rate
- analog units

This program has been verified through using the V370 system and Edmund
Cramp's C3D-Editor found at http://www.emgsrus.com.

N.B.2. This program is compatible with MATLAB v5.0 and above since it
writes the data into a three dimensional data array (frame,marker,axis)
and analog data into a three dimensional array
(frame[video],marker,timeslice), where the timeslice is equivalent to one
frame of the many analog frames that are sampled per video frame (ie. 4x
the sampling rate).


Have fun!

Alan Morris, M.A.Sc., P.Eng
Research Engineer - Gait Laboratory
Bloorview MacMillan Centre
350 Rumsey Road
Toronto, Ontario
CANADA
M4G-1R8
Tel (416) 425-6220 x3508
Fax (416) 425-1634
email morrisa@ecf.utoronto.ca

---------------------------PROGRAM LISTING--------------------------

function[coord,analog,nframes,sframe,eframe,frame_rate,nmar kers,adcperframe,nchannel,parameter]=readc3d(fname)
% READC3D: Getting 3D coordinate/analog data from .C3D binary file (V370/V140 version)
%
% Input: fname - file name to be read (or path)
%
% Output: coord - coordinate data [m] (nframes x (nmarkers*4) matrix)
% analog - analog data 16 bit [volts] (nfames x (nchannel*ADCframes/VICON) matrix)
% nframes - total number of VICON frames
% sframe - starting frame of data
% eframe - ending frame of data
% frame_rate - frame rate of VICON camera data
% nmarkers - number of coordinate markers
% adcperframe - number of analog frames per VICON frame
% nchannel - number of analog channels sampled
% parameter - 3-dimensional structure (group,parameter,datum)

% Author: Alan Morris
% Date: October 1998
% Institution: Bloorview MacMillan Centre (Gait Laboratory)
% 350 Rumsey Road
% Toronto, Ontario
% Canada M4G-1R8
% Tel (416) 425-6220 x3508 / Fax (416) 425-1634

% Open the file and skip the first 2 bytes
% Reading file in VAX D format
fid=fopen(fname,'r+','d');

% Reading record number of parameter section
key1=fread(fid,1,'int8');
key2=fread(fid,1,'int8');

fseek(fid,2,'bof');

% Getting all the necessary parameters from the header record
nmarkers=fread(fid,1,'int16'); %number of markers
nanalog=fread(fid,1,'int16'); %number of analog channels x #analog frames per video frame
sframe=fread(fid,1,'int16'); %# of first video frame
eframe=fread(fid,1,'int16'); %# of last video frame
nframes=eframe - sframe + 1; %number of frames
intgap=fread(fid,1,'int16'); %maximum interpolation gap allowed (in frame)
scale=fread(fid,1,'float32'); %floating-point scale factor to convert 3D-integers to ref system units
nstart=fread(fid,1,'int16'); %starting record number for 3D point and analog data
adcperframe=fread(fid,1,'int16'); %number of analog channels per video frame
fseek(fid,0,'cof');
frame_rate=fread(fid,1,'float32'); %frequency of video data
nchannel=nanalog/adcperframe; %number of analog channels

% Group Data/Parameter Records
fseek(fid,512,'bof');

% 1st group data only
dat1=fread(fid,1,'int8');
dat2=fread(fid,1,'int8');
records=fread(fid,1,'int8');
proctype=fread(fid,1,'int8');

% The end of the parameter record is indicated by 0 characters for group/parameter name
characters=fread(fid,1,'int8'); %characters in group/parametername
idnumber=fread(fid,1,'int8'); %id number -ve=group / +ve=parameter

while characters~=0

if idnumber0
parameter(idnumber,index,1).name=cellstr(char(name )); %save parameter name
end

% read offset and type
offset=fread(fid,1,'int16'); %offset of parameters in bytes
filepos=ftell(fid); %present file position
nextrec=filepos+offset(1)-2; %position of beginning of next record
type=fread(fid,1,'int8');

if type==-1
datatype='char'; %characters
elseif type==1
datatype='int8'; %1-byte for boolean
elseif type==2
datatype='int16'; %integer
else %type==4
datatype='float'; %floating-point number
end

parameter(idnumber,index,1).datatype=type; %type of data:-1=char/1=byte/2=integer*2/4=real*4

% read number of dimensions
dimnum=fread(fid,1,'int8');
parameter(idnumber,index,1).numdim=dimnum; %number of dimensions in parameter

for j=1:dimnum
dimension(j)=fread(fid,1,'int8');
parameter(idnumber,index,j).dim=dimension(j); %save parameter dimension data
end

if dimnum==0 %number of dimensions of the parameter
datalength=abs(type); %length of data record
else
mult=1;
for j=1:dimnum
mult=mult*parameter(idnumber,index,j).dim;
end

datalength=abs(type)*mult; %length of data record for multi-dimensional array
end


if type==-1 %datatype=='char' if data is a character string

wordlength=parameter(idnumber,index,1).dim; %length of character word

if dimnum==2 & datalength>0 %& parameter(idnumber,index,2).dim>0
for j=1:parameter(idnumber,index,2).dim
data=fread(fid,[1,wordlength],datatype); %character word data record for 2-D array
parameter(idnumber,index,j).data=cellstr(char(data ));
end

elseif dimnum==1 & datalength>0

data=fread(fid,[1,wordlength],datatype); %numerical data record of 1-D array
parameter(idnumber,index,1).data=cellstr(char(data ));

end

elseif type==2 & datalength>0 %integer

datum=datalength/abs(type); %number of data of numerical type

for j=1:datum
parameter(idnumber,index,j).data=fread(fid,1,datat ype); %parameter data
end

elseif type==4 & datalength>0

datum=datalength/abs(type);

for j=1:datum
parameter(idnumber,index,j).data=fread(fid,1,datat ype); %parameter data
end

else
datum=0;
end

deschars=fread(fid,1,'int8'); %description characters

if deschars>0
description=fread(fid,[1,deschars],'char');
parameter(idnumber,index,1).description=descriptio n;
end

%moving ahead to next record
fseek(fid,nextrec,'bof');

end

% check group/parameter characters and idnumber to see if more records present
characters=fread(fid,1,'int8');
idnumber=fread(fid,1,'int8');

end


%---------------------------------------------------------------------
% Get the scaled coordinate data [mm] and analog data
% using 3-dimensional coordinate arrays
fseek(fid,(nstart-1)*512,'bof');
for i=1:nframes

for j=1:nmarkers
for k=1:4
if scale < 0
coord(i,j,k)=fread(fid,1,'float32');
else
coord(i,j,k)=fread(fid,1,'int16')*scale;
end
end;
end;

for l=1:adcperframe
for m=1:nchannel
analog(i,m,l)=fread(fid,1,'int16')-2048; %zero the analog channel by subtracting 2048 bits
end;
end;

end;

fclose(fid);

-------------------------------------------------------------------
To unsubscribe send UNSUBSCRIBE BIOMCH-L to LISTSERV@nic.surfnet.nl
For information and archives: http://www.bme.ccf.org/isb/biomch-l
-------------------------------------------------------------------