Ich habe ein Projekt und möchte die ersten 250 ms einer Messung näher betrachten!
sprich ich habe eine Drehmoment Messung, und dazu EMG Signale und möchte mir nur die Entwicklung der ersten 250-300 ms ansehen - Um die Daten dann auch statistisch vergleichen zu können, wäre es super, wenn ich alle 10 ms einen RMS/FFT Wert bekäme!
ist das grundsätzlich möglich??
Würde mich freuen, könntet ihr mir so schnell wie möglich helfen!
Um dir aber wirklich weiterhelfen zu können, müsste man mehr wissen: wurden Daten schon erfolgreich eingelesen? Falls ja, für welchen Zeitbereich und in welcher Abtastung?
Je konkreter die Fragestellung und die Ausgangslage, desto konkreter meist auch die Antwort.
bin noch eher ein Matlab-Frischling und werd versuchen im Folgenden die Fragestellung zu konkretisieren:
Also die Daten wurden bereits erfolgreich eingelesen! Defacto habe ich eine Zeitspalte, Emg Spalte und Torque (Nm) Spalte!
Damit ich aber Aussagen über die Muskelarbeit bzw Kraftentwicklung tätigen kann, brauch ich die ersten 250ms (lt. Literatur) der Gesamten Messung. Ich möchte dann einen Plot mit Torque und EMG (y-Achse) und Zeit (x-Achse) im Intervall von [0-250ms] haben.
Fs=1500 Hz
(muss mir dann wahrscheinlich ausrechnen die Frames und wieviele Frames 250 ms Sekunden sind [...]
Sollten EMG und Torque eine recht unterschiedliche Skalierung haben, kann man plotyy verwenden oder mit subplot in zwei verschiedene Koordinatensysteme plotten.
Mehr Infos dazu jeweils in der Doku.
Falls du die Anzahl der benötigten Frames variieren kann (z.B. durch unterschiedliche Abtastzeiten von Messung zu Messung), als Alternative:
Code:
ind = t < 0.25; % 250 ms plot(t(ind ), EMG(ind ), t(ind ), Torque(ind ))
Vielen Dank Harald!!! hat mir echt super geholfen...
kennst Dich auch mit EMG Onset aus? Parallel arbeite ich an einem Projekt, um die aerob-anaerobe Schwelle zu finden, und habe ein 20 minütiges EMG Signal. Meine Idee wäre, über das gesamte Signal eine Funktion laufen zu lassen, welches mir automatisch On und Offset erkennt, und von den jeweiligen Burst die median Frequenz (FFT Window) und RMS berechnet.
Fs=2000 Hz
Das Programm mit dem ich arbeite, funktioniert zum einen nicht, zum anderen könnte ich die "Events" (Muskelkontraktionen) manuell definieren - ist natürlich ein bisschen kritisch zu betrachten, da ich der Einzige Begutachter bin und so mit zu subjektiv wird! mathematisch mit einem Programm wäre es da viel einfacher und genauer!
ah ok, ich glaub so weit war ich auch schon, jedoch findet er mir nur den ersten Onset bzw überschreibt dann alle anderen...
muss ich wahrscheinlich mit einer IF oder For Schleife arbeiten, dass ich Matlab quasi sagen kann,
IF onset --> find medianfrequenz im Intervall [Onset:Offset]
und das nicht nur für eine Muskelkontraktion, sondern für alle Burst der 20 minütigen Messung!
geht das eigentlich?
und damit ich dann in einem Statistikprogramm die Daten bekommen, bräuchte ich dann als Ausgabe einen Spaltenvektor n ter Länge, mit der Veränderung der Medianfrequenz bzw RMS über die Zeit. Laut Literatur wird auch die Medianfrequenz als Index für neuromuskuläre Ermüdung angegeben...
möchte mich im Vorfeld und im Nachhinein Bedanken, dass Du Deine wertvolle Zeit für mich opferst und mir in dieser Hinsicht wirklich sehr geholfen hast! Danke noch einmal...
ah ok, ich glaub so weit war ich auch schon, jedoch findet er mir nur den ersten Onset bzw überschreibt dann alle anderen...
Ja, mit dem bestehenden Code bekommt man genau einen Wert. Sollte aber doch auch logisch sein?
Zitat:
und das nicht nur für eine Muskelkontraktion, sondern für alle Burst der 20 minütigen Messung!
geht das eigentlich?
Dir mag zwar klar sein, was Muskelkontraktionen und Bursts in Bezug auf deine Daten sind, aber mir ist es das nicht. Natürlich kannst du dieselbe Analyse auf verschiedene Datenteile anwenden. Du musst aber in irgendeiner Form sagen, wie diese Datenteile aus den Daten identifiziert werden können.
Ich helfe gerne mit MATLAB-Fragen, habe aber leider (wie vermutlich die meisten hier) keine Ahnung von Neurologie. Daher bin ich darauf angewiesen, dass du die Problemstellung möglichst auf die zu verarbeitenden Zahlenkolonnen runterbrichst.
Denoch vielen Dank, ist ja nicht selbstverständlich...
(Leider kann ich keine Text Datein aus meinem Programm exportieren, da das Programm Spalten mit einander vermischt und dann die Vektoren unterschiedliche Längen haben!)
ich versuche eine matlab file in eine txt file um zuwandeln um diese dann hochzuladen!
Ein Burst= Muskelkontraktion!
Was ich bräuchte, wäre eine Funktion, die mir die Medianfrequenzen und RMS-Wert in den jeweiligen Intervallen (zwischen On und Offset) ausrechnet und mir in eine Spalte gibt. Danach tastet Matlab das Signal ab, findet den nächsten "Burst" und berechnet die Medianfrequenz im nächsten On-Offset-Intervall und schreibt das Ergebnis in die zuvorangelegte Spalte, unter die vorherige Medianfrequenz, usw... bis das Signal eben aus ist (etwa 20 MInuten) Als Ergebnis hätte ich dann gerne einen SPaltenvektore mit den jeweiligen Medianfrequenzen aller Muskelkontraktionen. (ich hoff ich habe es jetzt einigermaßen gut erklären können...)
mir ist nicht klar, was nun ein onset ist. Aus deiner anfänglichen Definition scheint es etwas mit den y-Werten zu tun zu haben, nun scheint es eher ein x-Wert zu sein.
Mir ist nun graphisch klar, was du machen möchtest. Der nächste Schritt wird sein, das in eine logische Bedingung zu formulieren. Ein erster Ansatz:
Code:
onset = find(diff(abs(EMG) > 100)); % starker Anstieg der Amplituden
offset = find(diff(abs(EMG) < 100)); % starker Abfall der Amplituden
Das kann man dann sicher noch anpassen, weil ja z.B. onset und offset abwechselnd aufeinander folgen müssen. Um dir da weiterhelfen zu können, bräuchte man einen Beispieldatensatz. .mat-Dateien lassen sich zwar nicht direkt anhängen, aber gezippt schon.
also ein Onset ist jener Zeitpunkt, wo der Muskel kontrahiert und der Offset ist dann die Ruhephase des Muskels. wenn ich die Medianfrequenz über die gesamte Aufzeichnung berechne, dann nimmt Matlab auch die "RuhePhasen" rein - sprich die Intervalle zwischen Offset und Onset. Damit ich die Medianfrequenz nur in der aktiven Phase des Muskels habe benötige ich wie gesagt nur das Intervall zwischen Onset und Offset. Mann kann auch aktive Phase (das ist graphisch jener rot eingekreister Bereich) und inaktive Phase (wo sich das Signal um den Nullpunkt bewegt) sagen...
tut mir wirklich leid, dass ich das so verwirrend erkläre...
Wenn ich das jetzt runterbreche muss ich das Signal in zwei Phasen einteilen:
1- Phase = inaktive Phase (Muskel kontrahiert nicht) ist in den Bildern auch gut zu sehen --> dort wo Das Signal um den Nulllinie rauscht
2-Phase = aktive Phase (Muskel kontrahiert) diese Phase ist dann rot markiert.
Matlab wird vermutlich für alle Onsets einen x-Wert berechnen und für alle Offsets einen zweiten x-Wert. Daraus ergibt sich ein Intervall (Bsp: im Bild "On-Offset": x-schwarz(onset) und x-rot(offset). Aus diesem Intervall möchte ich dann die median Frequenz berechnen bzw das RMS.
Wenn Matlab mit der Abtastung des Signals fertig ist, bekomme ich hoffentlich eine Spalte mit allen RMS Werten, und eine Spalte mit allen median Frequenzen, die Matlab in den jeweiligen ON-Offset Intervallen berechnet hat.
Im Anhang befindet sich eine rar Datei, mit Testdaten!
da die Daten auch in der aktiven Phase stark verrauscht sind, ist es für mich schwer, hier mit einer logischen Bedingung aufzuwarten.
Scheint mir hier Richtung Signalverarbeitung zu gehen, vielleicht sollte man das Signal vorher filtern, z.B. mit einem Tiefpassfilter um die hochfrequenten Anteile herauszufiltern.
ok, hab einen 5 Hz Butterworthfilter darüber gelegt um das Ganze zu filtern!
Weiters habe ich eine Funktion gefunden, die mir den Onset einer einzigen Kontraktion findet und dann plottet.
Code:
function onoff = emgonoff(rawemg, fs, ws, sd) % EMGONOFF - Find on/off times and indicies of raw EMG data. % Calculate average(mean) value of resting EMG % Define "on" EMG as the sample where average value of EMG in a given window % range around the sample is a given # of std. dev. above avg. resting EMG.
%
% onoff = emgonoff(rawemg, fs, ws, sd)
%
% Use the mouse to select two ranges of "resting" EMG from a graph of the % full-wave rectified EMG data. Click four times: start and end of 1st % resting range, and start and end of 2nd resting range. Mouse clicks need % to be consecutive and in order of increasing time (i.e. left-to-right on % the graph). The first range should precede the EMG burst associated with % the muscle contraction under consideration. The sedond range should be % the resting EMG data immediately following the EMG burst.
%
% rawemg = input file raw emg data (1-column vector) % fs = sampling rate of raw EMG data in Hz % ws = window size in milliseconds (50ms @ 2400Hz = 120 samples) % sd = number of std. deviations above resting rms emg to trigger an "ON" % Default values: % ws = 50ms % sd = 1
%% Check inputs for defaults ifnargin < 2, error('Not enough inputs. Type "help emgonoff" for help.'); end ifnargin < 3, ws = 50; end ifnargin < 4, sd = 1; end;
%% Full-Wave-Rectify the raw data
fwlo = abs(rawemg(:,1));
%% prepare for loop % Get two ranges for resting emg (before & after burst) using ginput
R = input('\nUse the mouse to select FOUR points to define the begining and \nend of two data ranges that will be used to calculate average\nresting EMG values before and after the EMG burst (muscle contraction)\nPress [RETURN] to begin: ');
clear R;
f1 = figure;
plot(fwlo);
[x y] = ginput(4); %click four times: two for start/end of resting emg before burst two for resting emg after burst
x = round(x);
clear y;
%close(f1);clear f1; % Leave commented if you want to keep EMG graph up to % % do a visual QA of on/off results.
%% preallocate arrays
mvgav = zeros(x(4)-x(1),1);
onoff(1,1) = 0;
i=0;
restav = mean(fwlo(x(1):x(2))); %average value of rest EMG before ON
reststd = std(fwlo(x(1):x(2))); %std. dev. of rest EMG before ON
restav2 = mean(fwlo(x(3):x(4))); %average value of rest EMG after OFF
reststd2 = std(fwlo(x(3):x(4))); %std. dev. of rest EMG after OFF
%% window size (in samples) = ws*fs e.g. 50ms*2400Hz = 120 samples
sws2 = fs*(0.001*ws);
sws = 0.5*(sws2);
sws = round(sws);
%% find "ON" index: % for xi, change from x(1) to x(2) if you want to ignore any "blips" % within the resting range.
%xi = x(1);
xi = x(2);
xi = round(xi);
for n = 2:length(mvgav);
mvgav(n,1) = mean(fwlo((xi-sws):(xi+sws)));
if mvgav(n) > restav+sd*reststd;
i = i+1;
onoff(i,1) = xi;
break end
xi = xi+1;
end
%% find "OFF" index: clear n xi i
mvgav2=zeros(x(4)-x(1),1);
i=0;
xi=onoff(1,1)+(1/2)*(x(3)-onoff(1,1)); %start OFF search approx. 1/2 way through ON burst.
%% OFF loop:
xi=round(xi);
for n=2:length(mvgav2);
mvgav2(n,1)=mean(fwlo((xi-sws):(xi+sws)));
if mvgav2(n)<restav2+sd*reststd2;
i=i+1;
onoff(i,2)=xi;
break end
xi=xi+1;
end
habe eine EMG Datei "100%.txt" hochgeladen damit man das ausprobieren kann! basierend auf dieser Funktion wäre es super, wenn ich eine Skript hätte, mit der ich das völlig automatisch über die gesamte Zeitdauer der Messung machen kann! Da man bei dieser Methode, 2 Punkte vor, und 2 Punkte nach dem Burst auswählen muss...
und bezogen auf die 100%.txt Datei hätte ich noch ein paar weitere Fragen:
1.) Kann man Geraden zwischen zwei Punkten plotten (bsp. Ursprung und Maximum) bzw wie kann ich die Steigung des ersten Anstiegs bis zum ersten Wendepunkt berechnen ?
2.) Habe beim Exportieren so meine Probleme! Ich möchte alle Spalten als txt. Datei exportieren, sodass ich eine Zeitspalte habe, und rechts davon die verschiedenen EMG Channels!
Ich glaub es war heut wieder ein bisschen verwirrend, aber wenn mir jemand Helfen kann, wäre das suuuuuper!!
2)
In welcher Form liegen die Daten denn an der Stelle, an der sie exportiert werden sollen, vor?
Wenn sie als Matrix oder Dataset Array vorliegen, sollte es an sich kein Problem sein.
ich hab jetzt versucht, eine if schleife zu erstellen:
Code:
if VMdextfilt==1
max_vmdext = find(max(VMdextfilt(0:0.300*Fs))); %findet das Maximum im intervall 0-300ms
wp_vmdext = find(diff(sign(diff(diff(VMdextfilt(0:0.300*Fs))))) ~= 0); %findet den Wendepunkt im Intervall 0-300ms
if wp_vmdext ==1
%find(x/y) zum Wendepunkt) plot([0:0],[x:y]);
%find Steigung der Geraden zwischen 0 und (x/y) end end
ich hab keine ahnung, ob man das so machen kann, oder ob das völlig daneben ist!
zum thema export:
Werte liegen in einer Dataset Array vor ("filename" <9000x1>double) und möcht gern dass exakt diese spalte als txt File ausgegeben wird, damit ich dann die Daten in Excel/SPSS einlesen kann...
zum Thema Onset:
Hast du da eine Idee, wie man das eventuell automatisch und über mehrere Muskelkontraktionen hinweg erstellen kann?
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.