Video Duration is not the same as my real time Recording
29 views (last 30 days)
Show older comments
I wrote a Code for live analysing a recorded Video. This works verry well but when I try to save it a a Video file my video is always shorter than my recording. Also my save Video is mirrowed at the y-Achsis, and i dont know why because the Live plot is not
This is the Code:
clc; clear; close all;
%% --- Parameter ---
FPS = 25; % Frames per second
baseFolder = '.';
timestamp = datestr(now,'yyyy-mm-dd_HH-MM-SS');
subFolder = fullfile(baseFolder,['Run_',timestamp]);
if ~exist(subFolder,'dir'), mkdir(subFolder); end
%% --- Camera initialisieren ---
vid = videoinput('gentl',1,'Mono8');
vid.FramesPerTrigger = Inf;
vid.TriggerRepeat = 0;
vid.LoggingMode = 'memory';
src = getselectedsource(vid);
disp('Kamera initialisiert.');
%% --- ROI Auswahl für drei Punkte ---
disp('Select the Left Point ROI.');
leftROI = selectAndSaveROI_TitleBased_2(vid,1);
disp('Select the Center Point ROI.');
centerROI = selectAndSaveROI_TitleBased_2(vid,2);
disp('Select the Right Point ROI.');
rightROI = selectAndSaveROI_TitleBased_2(vid,3);
%% --- Speedgoat / Simulink Setup ---
tg = slrealtime('TargetPC1');
disp(['Speedgoat Status: ', tg.status]);
mdl = 'test_Aurelio';
slbuild(mdl); % FPS muss vorher definiert sein
load(tg,mdl);
setStopTime(tg,inf);
%% --- KeyPressFcn zum Stoppen ---
stopFlag = false;
fig = figure('Name','Live Angle Tracking','NumberTitle','off');
set(fig,'KeyPressFcn',@(src,event) assignin('base','stopFlag',true));
%% --- Videoaufnahme starten ---
start(vid);
start(tg,'ReloadOnStop',true,'AutoImportFileLog',false,'ExportToBaseWorkspace',false);
disp('Hardware Trigger aktiv. Drücke ENTER in der Figure zum Stoppen.');
%% --- Initiale Punkte detektieren ---
while vid.FramesAvailable < 1
pause(0.01);
end
frame = getdata(vid,1);
statsLeft = regionprops(imcrop(frame,leftROI)<50,'Centroid');
statsCenter = regionprops(imcrop(frame,centerROI)<50,'Centroid');
statsRight = regionprops(imcrop(frame,rightROI)<50,'Centroid');
leftCentroid = statsLeft(1).Centroid + leftROI(1:2);
centerCentroid = statsCenter(1).Centroid + centerROI(1:2);
rightCentroid = statsRight(1).Centroid + rightROI(1:2);
%% --- PointTracker initialisieren ---
t_left = vision.PointTracker('MaxBidirectionalError',5);
t_center = vision.PointTracker('MaxBidirectionalError',5);
t_right = vision.PointTracker('MaxBidirectionalError',5);
initialize(t_left, leftCentroid, frame);
initialize(t_center, centerCentroid, frame);
initialize(t_right, rightCentroid, frame);
%% --- Live Figure vorbereiten ---
hImg = imshow(frame);
hold on;
hLine = plot(NaN, NaN, 'r-o', 'LineWidth', 2);
hText = text(10,20,'', 'Color','yellow','FontSize',12);
%% --- Frames zwischenspeichern ---
frames = {};
angles = [];
frameIdx = 0;
%% --- Live Tracking Loop ---
while ~stopFlag
if vid.FramesAvailable < 1
pause(0.005);
continue;
end
newFrames = getdata(vid, vid.FramesAvailable);
frame = newFrames(:,:,:,end);
frameIdx = frameIdx + 1;
frames{frameIdx} = frame;
% Punkte tracken
[leftPts, ~] = t_left(frame);
[centerPts, ~] = t_center(frame);
[rightPts, ~] = t_right(frame);
leftCentroid = mean(double(leftPts),1);
centerCentroid = mean(double(centerPts),1);
rightCentroid = mean(double(rightPts),1);
% Winkel berechnen
X = [leftCentroid(1), centerCentroid(1), rightCentroid(1)];
Y = [leftCentroid(2), centerCentroid(2), rightCentroid(2)];
p = polyfit(X,Y,1);
angleDeg = rad2deg(atan(p(1)));
angles(frameIdx,1) = angleDeg;
% Live Plot aktualisieren
set(hImg, 'CData', frame);
set(hLine, 'XData', X, 'YData', Y);
set(hText, 'String', ['Angle: ', num2str(angleDeg,'%.2f'),'°']);
drawnow limitrate;
end
%% --- Stop Hardware ---
stop(tg);
stop(vid);
%% --- Videos speichern ---
% Original Video
vidOrigFilename = fullfile(subFolder,'original_video.avi');
vOrig = VideoWriter(vidOrigFilename,'Motion JPEG AVI');
vOrig.FrameRate = FPS;
open(vOrig);
% Video mit Tracking Overlay
vidTrackFilename = fullfile(subFolder,'tracked_video.avi');
vTrack = VideoWriter(vidTrackFilename,'Motion JPEG AVI');
vTrack.FrameRate = FPS;
open(vTrack);
for k = 1:length(frames)
frameRGB = repmat(frames{k},[1,1,3]);
% Overlay nur für Tracking-Video
frameOverlay = insertShape(frameRGB,'Line',[leftCentroid, centerCentroid; centerCentroid, rightCentroid],'Color','red','LineWidth',2);
frameOverlay = insertMarker(frameOverlay,[leftCentroid; centerCentroid; rightCentroid], 'o', 'Color', 'yellow', 'Size',5);
frameOverlay = insertText(frameOverlay,[10,10],['Angle: ', num2str(angles(k),'%.2f')],'FontSize',12,'BoxColor','black','TextColor','yellow');
writeVideo(vOrig, im2uint8(flipud(frameRGB)));
writeVideo(vTrack, im2uint8(flipud(frameOverlay)));
end
close(vOrig);
close(vTrack);
%% --- Winkel Daten speichern ---
save(fullfile(subFolder,'angle_data.mat'),'angles');
disp('Alle Daten und Video gespeichert.');
%% --- Nachträglicher Plot ---
time = (0:length(angles)-1)/FPS;
fig1 = figure;
plot(time,angles,'LineWidth',2);
xlabel('Zeit [s]');
ylabel('Winkel [°]');
grid on;
title('Live getrackter Winkel des Balkens');
exportgraphics(fig1,fullfile(subFolder,'Angle.pdf'),'ContentType','vector');
0 Comments
Answers (1)
Ayush
on 19 Dec 2025 at 5:40
Hi Aurelio,
I understand the issue with the saved video being shorter and mirrored vertically compared to your live plot.
1) Video length being shorter:
This happens mainly due to two reasons in your code:
a) Only the Last Frame is Saved per Loop:
When you call
>> newFrames = getdata(vid, vid.FramesAvailable);
>> frame = newFrames(:,:,:,end);
>> frames{frameIdx} = frame;
If multiple frames are available, you only keep the latest one and discard the rest. This causes many frames to be skipped, resulting in a shorter (time-lapse) video.
b) Frames Left in Buffer After Stop:
When you stop the loop, there may still be frames left in the camera buffer that aren't processed or saved.
Recommended Solution:
To capture every frame, update your loop as follows:
while ~stopFlag
if vid.FramesAvailable < 1
pause(0.005);
continue;
end
newFrames = getdata(vid, vid.FramesAvailable);
numNew = size(newFrames, 4);
for i = 1:numNew
frameIdx = frameIdx + 1;
currentFrame = newFrames(:,:,:,i);
frames{frameIdx} = currentFrame;
% Perform tracking and plotting only on the latest frame for live view
if i == numNew
frame = currentFrame;
% [Your tracking and plotting code here]
set(hImg, 'CData', frame);
set(hLine, 'XData', X, 'YData', Y);
set(hText, 'String', ['Angle: ', num2str(angleDeg,'%.2f'),'°']);
drawnow limitrate;
end
% Store angles for every frame
angles(frameIdx,1) = angleDeg;
end
end
This way, you save every frame and your video length will match the recording.
2) Video getting mirrored:
The video is mirrored because you use "flipud" when saving frames (which flips images vertically). You can remove "flipud" from your saving code so the video orientation matches the live view. You can also refer to the following documentation to understand more about "flipud" function:
Hope this helps!
0 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!