Use of the fread function

9 views (last 30 days)
G Z
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!

Accepted Answer

Jan
Jan on 18 Jun 2013
Edited: Jan on 18 Jun 2013
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);
end
% 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);
else
Head.nAnalog = 0;
end
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
Start_Field2 = TRIAL.ACTUAL_START_FIELD;
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?!');
end
Start_Field = Start_Field2(1) + 65536 * Start_Field2(2);
Head.iFrame = Start_Field;
Head.fFrame = End_Field;
Head.nFrame = End_Field - Start_Field + 1;
end

More Answers (0)

Categories

Find more on Startup and Shutdown in Help Center and File Exchange

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!