Datenanalysefirma !
-
Hilft das?
http://www.openecg.net/tutorial1/index.html
-
Hi dnke für die Antworten,
@Gästchen, ne leider nicht, ich poste jetzt mal einen Teil der Schnittstellenbeschreibung !Gruß
ShadowEater
-
Hi,
hier ist die Schnittstellenbeschreibung, ich hab ein rar hochgeladen welches die betreffenden .tif in gut leserlicher Qualität enthält.
Ich hoffe Ihhr könnt damit was anfangen.
Wenn Ihr möchtet lade ich auch eine Probedatei rauf, die ham nur 5 KB!http://www.filehosting.at/files/download.php?file=665f4ced4769a3421578a754a3d5b059
Vielen Dank für eure Mühe vorab
ShadowEater
-
Moin
Die Datenstrucktur scheint doch vollständig beschrieben zu sein. Wo ist den das Problem?
Die ersten 60 Byte sind header, danach kommen die ECG Waveform data. jeder Sampel hat 12 Bit die entsprechend gespeichert werden. wie man jetzt aus 3 Byte wieder 2 12Bit sampels extrahiert steht auch drin. Der ganze waveform block muss auf eine 4 Byte trenze erweitert werden ( wird dann mit FF aufgefüllt )
Zumindest den Header solltest du auswerten können. Der datenstatz ist immer gleich lang, also sollte auch die länge der Waveform immer gleich bleiben. Das Datum ist auch drinn, ist soweit ich gesehen habe ein unix timestamp. sollte sich also auch finden und überprüfen lassen.
gruss.
-
Hi Termite,
Zumindest den Header solltest du auswerten können.
ja den Header auslesen scheint auch zu funktionieren, ich kann aus den Beschreibung auch rauslesen, dass der Head immer 60 Byte lang ist.
wie man jetzt aus 3 Byte wieder 2 12 Bit sampels extrahiert steht auch drin.
dann versteh ichs nicht, kannst Du da näher drauf eingehen ?
Ich komm an die Waveform Daten nicht ran. Da stehen nur Ascii Werte aber wie muß ich die interpretieren ???Gibt's ne Möglichkeit Dich per Mail zu erreichen, das wäre echt klasse ?
hoffnungsvoll
ShadowEater
-
Hier nochmal alle benötigten Files und Infos !
Ich hab noch das kleine unfertige Prog. von mir angehängt.
Ich probiere da jetzt schon tagelang dran rum aber ich steig durch die Schnittstellenbeschreibung einfach nicht ganz durch, wäre echt super wenn Ihr mir da weiterhelfen könntet !http://www.filehosting.at/files/download.php?file=8c4e15178fca9b45eaa118d3fd52a76b
Gruß und vielen Dank vorab
ShadowEater
-
Arbeitest du daran privat oder beruflich?
-
privat!
Warum ???
-
Moin
auf Seite 11 ist ein Teil der 12 Bit Darstellung beschrieben Punkt 4.2.2.2
in der Datei 44dbe22f.ecg sind die ersten Data Byts
12 34 56 78 9A BC [hex stelle]
00 04 40 00 04 40 [daten]die 12 Byte ergeben sich dann wie folgt
1. hexstellen 421 somit 400
2. hexstellen 563 somit 400
3. hexstellen A78 somit 400
4. hexstellen BC9 somit 400Bedeutet somit das aus 3 Bytes 2 12bit sampls werden.
uint8_t data[3] = { 0x00, 0x04, 0x40 }; uint16_t sampl[2] { 0, 0}; sampl[0] = data[0]; sampl[0] |= ( data[1] & 0x0F ) << 8; sampl[1] = ( data[1] & 0xF0 ) >> 4; sampl[1] |= data[2] << 4;
Fat 12 macht meines wissens auch so was ähnliches.
gruss
-
Du hast einen Fehler in deiner Header einlese Routine gemacht.
Die While-Schleife
int iHeaderEnd = 0; ... while (iHeaderEnd < 68) { f.read((char*)arrHeader,iHeaderEnd); iHeaderEnd++; }
macht so keinen Sinn.
Du überschreibst jedes mal deinen arrHeader mit neuen Informationen.
Wenn du dir die Funktionsbeschreibung von fstream::read durchliest, kommst
du schnell auf die richtige Anwendung dieser Methode:istream& read ( char* s, streamsize n ); Read block of data Reads a block of data of n characters and stores it in the array pointed by s.
Wenn du nun die gesamte Schleife durch
f.read((char*)arrHeader, 68);
ersetzt, liest er den Header auch richtig ein.
Zum überprüfen: offne eine ecg Datei mit einem Hexeditor und schau dir dort
den Hinhalt an.Hier mal die Versionnummer:
Vers. of Data format : E C G 10
Gruß mcr
EDIT: Die Ausgabe habe ich wie folgt geändert:
cout << "Vers. of Data format : " << arrHead[0] <<" " << arrHead[1] << " " << arrHead[2] << " " << (long)arrHead[3] << endl << endl;
Wie kommst du auf die Idee, die ersten 68 bytes für den Header zu verwenden? Bisher wurde doch hier im Thread über 60 bytes gesprochen.
-
Hi mcr und Termite,
vielen Dank für eure Hilfe, ich hab nur noch ein paar Fragen !@mcr
Stimmt hab den Fehler behoben und die Schleife ersetzt und selbstverständlich nur bis 60 Bytes !unsigned char* cEcgReadIn::LoadEcg() { fstream f; int iHeaderEnd = 0; f.open("44DBE2AD.ecg",ios::in | ios::binary); if (!f) { cout << "Fehler beim oeffnen der Datei...\n"; } f.read((char*)arrHeader, 60); f.close(); return arrHeader; }
Die Ausgabe hab ich auch abgeändert:
cout << "Vers. of Data format : " << arrHead[0] <<" " << arrHead[1] << " " << arrHead[2] << " " << (long)arrHead[3] << endl << endl;
Aber was ist mit den ECG Waveformdatas ?
Wie schreibe ich die in ein Array und wie geb ich sie wieder aus ?@Termite
OK, was ich verstehe ist dass ich 3 Byte in 2 zwölf Bit Blöcke umwandeln muß !
Ist auch klar dass die waveform Daten ab (inklusive) dem 60. Byte stehen, aber bis wohin ???
Deinen Code versehe ich leider nicht so ganz!
Wäre es zuviel verlangt wenn Du mir zeigen würdest (codemäßig) wie ich die kompletten Waveformdaten einer Datei in ein Array schreibe und diese ausgebe, dann steig ich da besser durch denke ich ?!Danke vorab für die Mühe und Hilfe
hoffnungsvoll
ShadowEater
-
ist was passiert, funktioniert es jetzt, funzt es nicht, gibt es nen neuen fehler...
-
Hi BitWax,
siehe ober
!
Gruß
ShadowEater
-
ah ok, war ich zu schnell
-
Kein Prob
,
kannst Du helfen
???
Gruß
Markus
-
ShadowEater schrieb:
Aber was ist mit den ECG Waveformdatas ?
Wie schreibe ich die in ein Array und wie geb ich sie wieder aus ?Hier wird dir wohl nicht viel anderes übrig bleiben, als mit malloc
und Konsorten dynamisch speicher anzulegen.Ich habe mir jetzt die Beschreibung nicht durchgelesen, so dass ich
dir hier nur allgemeine Tips geben kann.1. Leg dir Datentypen für die Wavedaten an, um sie zu speichern. 2. Verwende z.B. std::vector, um diese Daten zu speichern. 3. Lese nur einzelne Datensätze und speichere sie im std::vector 4. Dies (3) machst du solange, bis das Ende der Datei erreicht ist.
Ich hoffe, ich konnte dir ein paar Hilfestellungen geben.
Gruß mcr
-
Moin
+0C Number of ECG Waveform data [AC0D0000] = 3500 dec = 00000DAC hex
somit 3500 sampls a 12 bit macht somit 42000 bits
macht somit dann 5250 byts die dazu verwendet werden.+ 60 für den Header sind dann 5310
das ganze noch auf ein Vielfaches von 16 gebracht ergibt 5312 was dann auch mit der datei grösse übereinstimmt.
max = 0x00000DAC; unsigned char * dataInPtr; unsigned short int * samplBuffer = new unsigned short int [max]; int j = 60; /* for all sampls do */ for ( int i = 0; i < max; i++ ) { /* if even sampl */ if ( (i % 2) == 0 ) { /* add bit 0 to7 bit to sampl */ samplBuffer [i] = dataInPtr[j]; j++; /* add bit 8 to 11 bit to sampl */ samplBuffer [i] |= ( dataInPtr[j] & 0x0F ) << 8; } /* if odd sampl */ else { /* add bit 0 to 3 to the sampl */ samplBuffer [1] = ( dataInPtr[j] & 0xF0 ) >> 4; j++; /* add bit 4 to 11 to the sampl */ samplBuffer [1] |= dataInPtr[2] << 4; j++; } }
das bit geshiebe ist meiner meinung nach grundlage für c - Programmierer.
mit & kann man bits ausblenden (alles wo in der makse 0 ist verschwindet),
mit | kann man bits einblenden
mit << und >> kann man die bits nach links oder rechts verschieben.ggf einfach mal mit den operatoren spielen und schaun was da passiert
gruss
-
Danke für die schnelle Hilfe mcr und Termite,
@Termite
verstehe ich das richtig : samplBuffer ist das dynamische Ergebnisarray inwelchem alle benötigten Werte drinstehen ?Dann müsste diese Funktion doch korrekt sein oder ?
Beim kompilieren gibt es auch keine Fehler oder Warnungen aber bein ausführen:AX_ECG_ReadIn_01.exe hat ein Problem festgestellt und muss beendet werden.
unsigned short int * cEcgReadIn::LoadEcg() { fstream f; int iHeaderEnd = 0; f.open("44DBE2AD.ecg",ios::in | ios::binary); if (!f) { cout << "Fehler beim oeffnen der Datei...\n"; } f.read((char*)arrHeader, 60); f.close(); const max = 0x00000DAC; unsigned char * dataInPtr; unsigned short int * samplBuffer = new unsigned short int [max]; int j = 60; /* for all sampls do */ for ( int i = 0; i < max; i++ ) { /* if even sampl */ if ( (i % 2) == 0 ) { /* add bit 0 to7 bit to sampl */ samplBuffer [i] = dataInPtr[j]; j++; /* add bit 8 to 11 bit to sampl */ samplBuffer [i] |= ( dataInPtr[j] & 0x0F ) << 8; } /* if odd sampl */ else { /* add bit 0 to 3 to the sampl */ samplBuffer [1] = ( dataInPtr[j] & 0xF0 ) >> 4; j++; /* add bit 4 to 11 to the sampl */ samplBuffer [1] |= dataInPtr[2] << 4; j++; } } return samplBuffer; }
Ausgabe :
unsigned short int *samplearr; samplearr = EcgRead.LoadEcg(); cout << "Vers. of Data format : " << samplearr[0] <<" " << samplearr[1] << " " << samplearr[2] << " " << (long)samplearr[3] << endl << endl;
Ich habe das kleine Projekt der Übersichtlichkeit wegen nochmal bereinigt und raufgeladen !
BTW:Kennst Du irgendwelche Tuts, Bücher oder Skripte von Universitäten die sich mit solchen Bitschiebereien beschäftigen (Aufgaben mit Lösungen wären gut) denn in allen meinen Büchern wird nur beschrieben dass es das gibt und es wird nur sehr kurz darauf eingegangen aber nichts wirklich beispielhaft erklärt !???
Vielen Dank für Deine / Eure Mühe und Hilfe
Gruß
ShadowEater
-
ShadowEater schrieb:
Danke für die schnelle Hilfe mcr und Termite,
@Termite
verstehe ich das richtig : samplBuffer ist das dynamische Ergebnisarray inwelchem alle benötigten Werte drinstehen ?Dann müsste diese Funktion doch korrekt sein oder ?
Beim kompilieren gibt es auch keine Fehler oder Warnungen aber bein ausführen:AX_ECG_ReadIn_01.exe hat ein Problem festgestellt und muss beendet werden.
unsigned short int * cEcgReadIn::LoadEcg() { fstream f; int iHeaderEnd = 0; f.open("44DBE2AD.ecg",ios::in | ios::binary); if (!f) { cout << "Fehler beim oeffnen der Datei...\n"; } f.read((char*)arrHeader, 60); f.close(); const max = 0x00000DAC; unsigned char * dataInPtr; unsigned short int * samplBuffer = new unsigned short int [max]; int j = 60; /* for all sampls do */ for ( int i = 0; i < max; i++ ) { /* if even sampl */ if ( (i % 2) == 0 ) { /* add bit 0 to7 bit to sampl */ samplBuffer [i] = dataInPtr[j]; j++; /* add bit 8 to 11 bit to sampl */ samplBuffer [i] |= ( dataInPtr[j] & 0x0F ) << 8; } /* if odd sampl */ else { /* add bit 0 to 3 to the sampl */ samplBuffer [1] = ( dataInPtr[j] & 0xF0 ) >> 4; j++; /* add bit 4 to 11 to the sampl */ samplBuffer [1] |= dataInPtr[2] << 4; j++; } } return samplBuffer; }
Ausgabe :
unsigned short int *samplearr; samplearr = EcgRead.LoadEcg(); cout << "Vers. of Data format : " << samplearr[0] <<" " << samplearr[1] << " " << samplearr[2] << " " << (long)samplearr[3] << endl << endl;
Ich habe das kleine Projekt der Übersichtlichkeit wegen nochmal bereinigt und raufgeladen !
http://www.filehosting.at/files/download.php?file=51ac8cb9f6f5306f68246b1d66c3c55e
BTW:Kennst Du irgendwelche Tuts, Bücher oder Skripte von Universitäten die sich mit solchen Bitschiebereien beschäftigen (Aufgaben mit Lösungen wären gut) denn in allen meinen Büchern wird nur beschrieben dass es das gibt und es wird nur sehr kurz darauf eingegangen aber nichts wirklich beispielhaft erklärt !???
Vielen Dank für Deine / Eure Mühe und Hilfe
Gruß
ShadowEater
-
Hi,
ich hab nen Fehler gefunden :
long max = 0x00000DAC; unsigned char * dataInPtr = new unsigned char[max]; unsigned short int * samplBuffer = new unsigned short int [max]; int j = 60; /* for all sampls do */ for ( int i = 0; i < max; i++ ) { /* if even sampl */ if ( (i % 2) == 0 ) { /* add bit 0 to7 bit to sampl */ samplBuffer [i] = dataInPtr[j]; j++; /* add bit 8 to 11 bit to sampl */ samplBuffer [i] |= ( dataInPtr[j] & 0x0F ) << 8; }
dataInPtr muß dynamisch sein, da ein paar Zeilen weiter dataInPtr einem dynamischen Array zugewiesen wird samplBuffer [i] = dataInPtr[j]; !
Ausgabe:
long max = 0x00000DAC; unsigned short int * samplBuffer = new unsigned short int [max]; samplBuffer = EcgRead.LoadEcg(); cout << samplBuffer[0] <<" " << (long)samplBuffer[1] << " " << samplBuffer[2] << " " << samplBuffer[3] << endl << endl;
Auf dem Screen wird dann :
3533 3292 3533 52685 ausgegen, aber das stimmt doch nicht ...!!!???Gruß
ShadowEater