MATLAB Answers


Use of the fread function

Asked by G Z
on 18 Jun 2013

Hey I'm trying to open .c3d files by the means of the fread function The problem I have is when searching the first frame and the last frame of the file with fread(fid,1,'int16') with fid = 8; If I do it with some non heavy files, I got a startframe = 1 and a endframe =~ 26000 and the script works but if I do it with more heavy files, then I got an enframe =~ -12000 which makes the script wrong and me angry ;) Sure someone has an idea... Thanks in advance!




No products are associated with this question.

1 Answer

Answer by Jan Simon
on 18 Jun 2013
Edited by Jan Simon
on 18 Jun 2013
 Accepted answer

When the C3D file format has been invented, large measurement files have been rare and int16 seemed to be a valid range for the number of frames. Many modern software packages use uint16 instead, because a negative number of frames is not valid at all.

I use this to import the header of C3Ds:

I8  = 'int8';
I16 = 'int16';
U16 = 'uint16';   % Signed is not meaningful!
F32 = 'float32';
% Spool to the beginning:
fseek(FID, 0, 'bof');
% Reading record number of parameter section:
Head.ParamRec = fread(FID, 1, I8);
MagicKey      = fread(FID, 1, I8);
if isequal(MagicKey, 80) == 0
   error(['JSimon:', mfilename, ':BadMagicKey'], 'Bad magic key: %d', MagicKey);
% Getting all the necessary parameters from the header record
Head.nCoor       = fread(FID, 1, U16);  % number of trajectories
Head.AnalogChunk = fread(FID, 1, U16);  % analog values per video frame
Head.iFrame      = fread(FID, 1, U16);  % index of first video frame
Head.fFrame      = fread(FID, 1, U16);  % index of last video frame
Head.MaxGap      = fread(FID, 1, U16);  % max allowed interpolation gaps
Scale            = fread(FID, 1, F32);  % scale integers to ref. units
Head.DataRec     = fread(FID, 1, U16);  % 1st record of data section
Head.AnalogRate  = fread(FID, 1, U16);  % analog samples per video frame
Head.VideoFreq   = fread(FID, 1, F32);  % frequency of video data
% If scale is negative, the data is stored in float format:
Head.FloatMode = (Scale < 0.0);
Head.Scale     = abs(Scale);
% Number of frames:
Head.nFrame = Head.fFrame - Head.iFrame + 1;
% Number of analog channels (FRC + EMG + ?):
if Head.AnalogRate  % Avoid division by zero:
   Head.nAnalog = round(Head.AnalogChunk / Head.AnalogRate);
   Head.nAnalog = 0;

But note, that today even the range of UINT16 is small and e.g. Vicon software write the actual number of frames to the parameter section as TRIAL.ACTUAL_START_FIELD and TRIAL.ACTUAL_END_FIELD. Then we need to modify the values:

End_Field2   = TRIAL.ACTUAL_END_FIELD;  % Or how ever you obtain parameters
End_Field = End_Field2(1) + 65536 * End_Field2(2);
if ~isequal(End_Field, Head.fFrame)
    if Head.fFrame ~= 65535
       warning(['GetC3D:', mfilename, ':Unexpected_nFrame'], ...
          'Long C3D, but [Head.fFrame] is not 65535?!');
      Start_Field = Start_Field2(1) + 65536 * Start_Field2(2);
      Head.iFrame = Start_Field;
      Head.fFrame = End_Field;
      Head.nFrame = End_Field - Start_Field + 1;


Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply today