Ich hatte vor ein paar Tagen die Möglichkeit auf einem heißen Sitz platz zu nehmen. Genauer gesagt auf dem Beifahrersitz eines BMW M3 3.2 E36, welcher von einem geschätzten Kollegen über den Eurospeedway Lausitzring bewegt wurde. Dazu habe ich mir eine Kamera und eine V-Box Mini geschnappt (danke an alle Beteiligten!) und ein paar Fahrdynamikdaten aufgezeichnet.
Wenn man genug Kleingeld hat, kann man ein fix und fertiges System kaufen, mit welchem Daten+Video synchron aufgezeichnet werden. Racelogic hat das z.B. im Angebot. Ich möchte im Folgenden zeigen, wie man aus Video und Daten trotzdem eine annehmbare Datenvisualisierung produzieren kann.
Datenaufzeichnung
Die Racelogic V-Box Mini zeichnet mit 10Hz die aktuelle Position (GPS), Längs- und Querbeschleunigung, Geschwindigkeit und auch Fahrtrichtung auf. Diese stehen dann über die Racelogic Software zur Verfügung. Der Export der Daten kann in .vbo (und dann mit einem VBO/Matlab Converter), “CommaSeparatedValues” .csv Textdatei oder auch nach Excel .xls erfolgen. Ich habe die Daten in eine Excel Datei exportiert:
Download Fahrdynamikdaten BMW M3 Eurospeedway Lausitzring
Das Video kam von einer GoPro HD, welche an der Frontscheibe fixiert war. Die Umwandlung von .mp4 in .avi geschah mit dem Pazera Free MP4 to AVI Converter.
Matlab Script zur Darstellung von Daten in einem Video
Einen Großteil der Zeit habe ich mit hin & her probieren von Codecs und Versionen verbracht. Das ist ärgerlich. Letztendlich habe ich folgende Variante gewählt: Ich habe zum Einlesen des (komprimierten) AVI Files einen DirectShow (DirectX) based AVI File reader aus dem Matlab Central geladen und diesen über addpath zu den Matlab-Functions hinzugefügt. Damit war es dann auch möglich Videodateien größer 2GB einzulesen und auch die standard Windows Codecs werden erkannt. Ich benutze die Matlab Version 2006b, diese ist sowas von überholt wenn es um Videobearbeitung geht, dass man leider ein paar Umwege gehen muss.
1. Überprüfen ob DirectShow based AVI File reader installiert wurde
clear all, close all, clc %% Checken ob Videofunction installiert wurde von % http://www.mathworks.com/matlabcentral/fileexchange/9901 check = exist('dxAviOpen'); if check == 0 disp('Bitte DirectShow (DirectX) based AVI file reader laden:') disp('http://www.mathworks.com/matlabcentral/fileexchange/9901') disp('und diesen über addpath() oder pathtool einbinden') warndlg({'Bitte DirectShow (DirectX) based AVI file reader laden:';... 'http://www.mathworks.com/matlabcentral/fileexchange/9901'}) return end
2. Excel Datei öffnen und in Workspace laden
%% open data file [filename,path] = uigetfile('*.xls', 'Load XLS File'); if (isequal(filename, 0)) return;% cancel end data = xlsread(fullfile(path,filename)); %% Variablen Fahrdynamik t = data(:,1); %Zeit in s v = data(:,2); %Geschwindigkeit in km/h ay = data(:,3); %Querbeschleunigung in g ax = data(:,4); %Längsbeschleunigung in g yaw = data(:,5); %Fahrtrichtung in Grad vv = data(:,6); %Vertical Speed in km/h nu = data(:,7); %Anzahl Satelliten B = data(:,8); %Breitengrad in min L = data(:,9); %Längengrad in min s = data(:,10);%Weg in m R = data(:,12);%Kurvenradius in m %% Querbeschleunigung filtern ayf = filter(ones(1,5)/5,1,ay);
3. Videodatei mit Matlab einlesen
%% open video file [filename,path] = uigetfile('*.avi', 'Select AVI File'); if (isequal(filename, 0)) return; % cancel end file_avi = fullfile(path,filename); % dxAviOpen ist eine Function von Matlabcentral % http://www.mathworks.com/matlabcentral/fileexchange/9901 [avi_hdl, avi_inf] = dxAviOpen(file_avi); fps = round(avi_inf.fps); frames = avi_inf.NumFrames; offset = -2.5; % Offset Video/Daten
4. Figure erzeugen worin Bilder + Daten angezeigt werden
%% Figure erzeugen fig = figure(1); set(fig,'Position',[100 100 avi_inf.Width avi_inf.Height],'MenuBar','none'); clf; ax0 = axes('Position',[0 0 1 1]); % dxAviReadMex ist eine Function von Matlabcentral % http://www.mathworks.com/matlabcentral/fileexchange/9901 pixmap = dxAviReadMex(avi_hdl, 1); pic = reshape(pixmap,[avi_inf.Height,avi_inf.Width,3])/256; bild = image(pic); axis off daspect([1 1 1]);
5. Dummys der Datenvisualisierungen erstellen
% Geschwindigkeitsdummy vorbereiten vh = text('Position',[0.5 0.1],'Units','normalized','String','0',... 'Color','g','FontSize',32,'FontName',... 'Tahoma','HorizontalAlignment','center'); text('Position',[0.5 0.04],'Units','normalized','String','km/h',... 'Color','g','FontSize',10,'FontName',... 'Tahoma','HorizontalAlignment','center'); % Querbeschleunigungsbar Dummy erzeugen (rechts) axr = axes('Position',[0.6 0.05 0.38 0.05]); aybarr = barh(0,0); set(axr,'Color','none','YColor','k','XColor','w',... 'XTick',[0.2 0.4 0.6 0.8 1.0 1.2 1.4],... 'YTick',[-1 1.4],'XGrid','on','FontName','Tahoma'); xlim([0.1 1.4]) % Querbeschleunigungsbar Dummy erzeugen (links) axl = axes('Position',[0.02 0.05 0.38 0.05]); aybarl = barh(0,0); set(axl,'Color','none','YColor','k','XColor','w',... 'XTick',[-1.4 -1.2 -1.0 -0.8 -0.6 -0.4 -0.2],... 'YTick',[-1 1.4],'XGrid','on','FontName','Tahoma'); xlim([-1.4 -0.1]) % Map hinterlegen vorbereiten % Index für eine Runde start = 4262; stop = 5594; axmap = axes('Position',[0.8 0.7 0.18 0.28]); line(B(start:stop),L(start:stop),'LineWidth',3,'color','black') axis([3091.68 3092.16 -836.2 -835.3]) axis off % Position Dummy erzeugen axpos = axes('Position',[0.8 0.7 0.18 0.28]); pos = line('XData',B(1),'YData',L(1),'LineWidth',1,'Marker',... 'o','MarkerSize',10,'MarkerFaceColor','g'); axis([3091.68 3092.16 -836.2 -835.3]) axis off
6. Videoframes einlesen, Daten darüber legen und abspeichern
%% Neues Video vorbereiten k=0; % k ist der Zähler für die Outputvideodateien, wenn >2GB new_mov = avifile(['GoProData' num2str(k) '.avi'],... 'compression','none','quality',100,'fps',fps); for i=1:frames %Frame für Frame abarbeiten clc disp([num2str(round(i*100/frames)) '% completed']) %Fortschritt zeit = i/fps + offset; % Zeitbezug herstellen % dxAviReadMex ist eine Function von Matlabcentral % http://www.mathworks.com/matlabcentral/fileexchange/9901 pixmap = dxAviReadMex(avi_hdl, i); pic = reshape(pixmap,[avi_inf.Height,avi_inf.Width,3])/256; set(bild,'CData',pic); % Bild aktualisieren index = find(t(:,1)<zeit,1,'last'); % Wert zum aktuellen Frame finden % Querbeschleunigung in Balken anzeigen if ayf(index)>0 %Linkskurve set(aybarr,'YData',ayf(index)) set(aybarl,'Ydata',0) else set(aybarl,'YData',ayf(index)) set(aybarr,'YData',0) end % Geschwindigkeit setzen set(vh,'String',num2str(round(v(index)))); % Position setzen set(pos,'YData',L(index),'XData',B(index)); drawnow new_mov = addframe(new_mov,getframe(fig)); % 2 GB Dateigrößengrenze beachten s = dir(['GoProData' num2str(k) '.avi']); if s.bytes >= 2e9 % wenn > 2GB eine neue anlegen new_mov = close(new_mov); k=k+1; new_mov = avifile(['GoProData' num2str(k) '.avi'],... 'compression','none','quality',100,'fps',fps); end end
7. Videodatei schließen
new_mov = close(new_mov); % File schließen close all; % Figure schließen
Nachbearbeitung der Videofiles
Wie im Matlab Code zu sehen ist, erzeugt das Script unkomprimierte AVI Files ohne Ton. Diese sind auf ~2GB gesplittet abgespeichert. Nachträglich muss dann noch die Tonspur des Originalvideos mit den Videoteilen zusammengesetzt werden. Das kann man z.B. mit Microsofts Live Movie Maker erledigen. In diesem Fall mit 14min Video in 848x480px Auflösung ergibt sich eine Datenmenge von 25GB, diese sollte man auf der Festplatte zur Verfügung haben.
One Comment