Aus Datei lesen
-
Hey Leute,
ich habe eine Aufgabe, an der ich schon stundenlang sitze , aber keinen Schritt weiterkomme.Prinzip ist grob, dass wir eine DICOM-Datei vorgegeben haben und aus der sollen wir alle Bildpunkte auslesen und dann bestimmte Punkte ändern, sodass sich dann letztendlich die Farben im Bild ändern.
Mein Problem ist allerdings, dass ich nicht genau weiß wie ich die Bildpunkte auslese, da ich keinerlei Informationen darüber vorgegeben habe, nur dass die Bildpunkte nach der hexadezimale Zahlenkombination (0x7FE0,0x0010), und dann noch 4 char variablen überspringen, anfangen.
An die Stelle soll ich wohl mit fseek springen und dann anfangen die Bildpunkte eines 512x512 großen Bildes auszulesen.Hab leider gar keinen Ansatz.
Letztens hatte ich ähnliches, aber mit vorgegebenem header-Dateien und hier weiß ich gar nicht wie und woraus ich irgendwie lesen soll.Gruß,
basti
-
Ich würd mal sagen: Das hier wär wohl ein guter Anfang.
-
könnte man dann mit:
fseek(pFile,(short)132*sizeof(char),0);
an den Anfang der Bildpunkte springen?
Wenn ja, wie liest man dann die Punkte aus?
-
basti273 schrieb:
könnte man dann mit:
fseek(pFile,(short)132*sizeof(char),0);
an den Anfang der Bildpunkte springen?
Das (short) ist überflüssig, sizeof(char) ist per default 1.
Und für die 0 gibt es das Makro SEEK_SETDie Kennung ab Position 128 solltest du zur Sicherheit auch mit einlesen.
Dann weißt du, dass dein Format richtig ist.basti273 schrieb:
Wenn ja, wie liest man dann die Punkte aus?
Wie ist denn das Format von den Daten, hast du da schon was rausgefunden?
Binärdaten kanns tu mit fread oder fgetc lesen.
Du musst aber auf die Bytereihenfolge achten.
-
Bin jetzt mit folgendem an den ersten Bildpunkt gesprungen.
fseek(pFile, 128*sizeof(char), SEEK_SET); fseek(pFile, 4*sizeof(char), SEEK_CUR);
Ja, als Tipp wurde vorgegeben, die Bildpunkte als short auslesen zu lassen.
Dann soll man jeden einzelnen Punkt auslesen im Wert ändern.
Aber das auslesen klappt nicht.bei fread fehlt mir auch irgendwie immer was...
Weiß da nicht so recht, wie ich da rauslesen soll, da ich iwie keine bestimmte adresse habe.
-
Dann zeig mal etwas mehr Code.
Auf welchem System und mit welchem Compiler arbeitest du?
Das auslesen als short soll vermutlich ein 16-Bit-Integer (2 Byte) bedeuten.
Was sagt denn die Dokumentation zur Bytereihenfolge?
-
Ich arbeite mit Microsoft Visual Studio.
#include <stdio.h> #define SIZE 50 int main(void) { FILE *pFile; char filename[SIZE]; printf("Welche Datei wollen sie oeffnen: "); scanf("%s", &filename); pFile = fopen(filename,"rb"); if(pFile) { printf("Datei wurde geoeffnet!\n"); fclose(pFile); } else { printf("Datei konnte nicht gefunden werden.\n"); } pFile = fopen(filename, "rb"); fseek(pFile, 128*sizeof(char), SEEK_SET); fseek(pFile, 4*sizeof(char), SEEK_CUR); printf("\n\n"); return 0; }
"Also am Anfang überprüfen, ob es die Datei gibt und dann öffnen und an die erste Stelle des Bildes springen, den header sozusagen überspringen. Zunachst kommt der so genannte Header der Datei, der eine Menge an anderen Informationen enthalt (um die wir uns NICHT kummern) und auch eine variable Groe besitzt. Danach kommt an einer bestimmten Stelle die Information, dass nun die Bilddaten kommen. Diese Information ndet sich dadurch, dass man die Daten (als short!) einliest und wenn die hexadezimale Zahlenkombination (0x7FE0,0x0010) gefunden wird, mussen noch vier char-Daten ubersprungen werden, dann kommt als long die Anzahl der Bildpunkte und dann beginnen die Bilddaten (nachzulesen im DICOM-Standard). Die Groe der Bilder ist (bei der Computertomographie) 512 512 und die Bilddaten sind als short- Variablen gespeichert."
Das wär der Auszug zum Auslesen, der Schritt fehlt mir eigentlich.
Brauch ich da nicht iwie auch einen Pointer auf die Bildpunkte? Hab ich auch nicht so wirklich.
Muss ja jeden Bildpunkt abtasten und auslesen.Für den fseek(); befehl muss ich ein anderen pointer als den FILE pointer nehmen oder?
-
#include <stdio.h> #define SIZE 50 int main(void) { FILE *pFile; char filename[SIZE]; // Wo sollen denn deine Daten gespeichert werden ? printf("Welche Datei wollen sie oeffnen: "); scanf("%s", &filename); // Da ^ kommt bei Arrays kein & hin pFile = fopen(filename,"rb"); if(pFile) { printf("Datei wurde geoeffnet!\n"); fclose(pFile); } else { printf("Datei konnte nicht gefunden werden.\n"); // Und was jetzt? Dein Programm läuft weiter als wäre nichts gewesen } pFile = fopen(filename, "rb"); fseek(pFile, 128*sizeof(char), SEEK_SET); fseek(pFile, 4*sizeof(char), SEEK_CUR); // wo ist das lesen mit dem du Schwierigkeiten hast? printf("\n\n"); return 0; }
Bitte poste hier deinen Code mit dem du arbeitest (per Copy and Paste)
-
#include <stdio.h> #define SIZE 50 int main(void) { FILE *pFile; char filename[SIZE], pixelarray[512][512]; // ins pixelarray sollen die werte gespeichert werden char *pixptr = pixelarray; int bildgroesse, bildhoehe=512, bildbreite=512, i, j; printf("Welche Datei wollen sie oeffnen: "); scanf("%s", filename); // kein & mehr pFile = fopen(filename,"rb"); if(pFile) { printf("Datei wurde geoeffnet!\n"); fclose(pFile); pFile = fopen(filename, "rb"); fseek(pFile, 128*sizeof(char), SEEK_SET); fseek(pFile, 4*sizeof(char), SEEK_CUR); fread(&pixptr, sizeof(short), 1, pFile); // auslesen der daten mit fread... aber bin nicht sicher, ob das mit dem pixptr richtig ist... bildgroesse = bildbreite*bildhoehe; printf("Die Bildgroesse ist %d Bytes.", bildgroesse); for(i=0; i<bildhoehe; i++) // jeden bildpunkt abtasten { for(j=0; j<bildbreite; j++) { if(pixelarray[i][j] < -900 || pixelarray[i][j] > 250) { pixelarray[i][j] = -1024; } } } } else // die schleife jetzt am ende, damit das programm danach nicht weiterläuft { printf("Datei konnte nicht gefunden werden.\n"); } printf("\n\n"); return 0; }
jetzt weiß ich nicht so wirklich weiter, brauch iwie glaub ich ein anderen pointer oder das array anders...
-
... char filename[SIZE], pixelarray[512][512]; // ins pixelarray sollen die werte gespeichert werden char *pixptr = pixelarray; ... pFile = fopen(filename,"rb"); if(pFile) { printf("Datei wurde geoeffnet!\n"); fclose(pFile); :arrow_right: // Was soll denn der Mist :confused: fclose und gleich danach fopen? pFile = fopen(filename, "rb"); ... fread(&pixptr, sizeof(short), 1, pFile); // auslesen der daten mit fread... aber bin nicht sicher, ob das mit dem pixptr richtig ist... :arrow_right: // Du liest gerade genau 1 short ein und nicht etwa 512x512 :arrow_right: // Zudem ist pixptr schon ein Pointer und der braucht hier kein & mehr bildgroesse = bildbreite*bildhoehe; :arrow_right: // zu spät. musst du früher machen printf("Die Bildgroesse ist %d Bytes.", bildgroesse); ... if(pixelarray[i][j] < -900 || pixelarray[i][j] > 250) :arrow_right: // pixelarray ist ein Array das char-Element aufnimmt. Wie willst du da Werte < 128 und > 127 drin abspeichern? ... pixelarray[i][j] = -1024; else // die schleife jetzt am ende, damit das programm danach nicht weiterläuft :arrow_right: // if ist keine Schleife sondern eine Bedingung ... }
basti273 schrieb:
jetzt weiß ich nicht so wirklich weiter, brauch iwie glaub ich ein anderen pointer oder das array anders...
Du brauchst ein C-Buch und das Kapitel über Arrays und Pointer.
Woher kennst du die Bildgröße?
Mach dir erst einmal klar was du einlesen willst.
Von welchem Typ sind die Daten? char, short oder sonstwas.
-
Und wenn ihr Bildpunkte verändern solt, müssen die auch irgendwie wieder in eine Datei.
Vielleicht solltest du den Header nicht überspringen sondern in ein Array einlesen und dann später wieder in die neue Datei schreiben.Versuch doch mal die 4 Zeichen ab Position 128 einzulesen und gib sie auf dem Bildschirm aus. Wenn das klappt hast du schon mal ein Gefühl für "Aus Datei lesen".
Zudem sieht das DICOM Format nicht ganz so trivial aus, wie du es gerade versuchst.
-
Ja, genau.
Eine neue Datei soll dann danach auch erstellt werden , indem wir die neuen Werte schreiben.
-
basti273 schrieb:
char filename[SIZE], pixelarray[512][512]; // ins pixelarray sollen die werte gespeichert werden
Mehrfach wird erwähnt, dass du mit short arbeiten sollst. Du hast aber hier ein char-Array. Was soll das bringen?
-
Ohja, ganz übersehen, stimmt. Danke für all die Hilfe, hab es vom prinzip her jetzt soweit fertig alles, allerdings hab ich noch ein problem mit dem finden des Dateianfangs.
Man muss ja solange Werte überspringen, bis man diese vorgegebene hexadezimalzahl findet. Aber wie kann ich diese suchen?int main(void) { FILE *pFile; char filename[SIZE], filenamenew[SIZE]; char ueber; short pixelarray[MAX][MAX]; short *pixptr = pixelarray[MAX]; int bildgroesse, bildhoehe=MAX, bildbreite=MAX, i, j; int hilf; int *hilfptr = &hilf; printf("Welche Datei wollen sie oeffnen: "); scanf("%s", filename); pFile = fopen(filename,"rb"); if(pFile) { printf("Datei wurde geoeffnet!\n"); fseek(pFile, 0*sizeof(char), SEEK_SET); //Dateianfang do { fseek(pFile, 1*sizeof(char), SEEK_CUR); fread(hilfptr, sizeof(short), 1, pFile); hilfptr++; }while(*hilfptr!=0x7FE0); fseek(pFile, 4*sizeof(char), SEEK_CUR); printf("Bildanfang"); ...
bei der do-while-schleife schmiert das programm immer ab, weil ich glaube dass der hilfptr nicht richtig funktioniert, aber wie finde ich die 0x7FE0 korrekt?
-
1. sizeof(char) ist 1 per Definition
2. Alle Lese/Schreiboperationen wie fread stellen den internen Dateizeiger automatisch weiter. Da braucht es kein fseek mehr (Zeile 25)
3. Ein Zeiger muss irgendwohin zeigen, wo es auch gültigen Speicher gibt.
(Wenn du darauf zugreifst)
4. Wenn du short einlesen willst/sollst, dann nimm auch eine short Variable.Dein hilfptr zeigt am Anfang auf hilf (das ist ein Integer) und durch das
hilfptr++;
dann irgendwohin, wo es nicht mehr sinnvoll ist.short hilf; do { fread( &hilf, sizeof(short), 1, pFile); // Das & da ^ liefert die Adresse der Variablen hilf } while(hilf != 0x7FE0);
-
Perfekt, mit der do-schleife funktioniert das Ding nun endlich.
Hatte das mit dem fread und dem automatischen überspringen nicht mehr ganz in Erinnerung gehabt.Allerdings haut der mir jetzt noch einen Fehler beim einlesen der Daten raus...
Ich kopier mal die wichtigen stellen rein, wo er einliest und die deklarationen.#define SIZE 50 #define MAX 512 int main(void) { FILE *pFile; char filename[SIZE], filenamenew[SIZE]; short pixelarray[MAX][MAX]={0}; short *pixptr = pixelarray[MAX]; int bildgroesse, bildhoehe=MAX, bildbreite=MAX, i, j; short hilf; // der platz dazwischen for(i=0; i<bildhoehe; i++) { fread(pixptr[i], sizeof(short), bildbreite,pFile); } // und danach kommt auch noch was
Was ist da der Fehler bei fread, bzw. besser, wie kriege ich den Weg?
hab da nämlich schon allerlei ausprobiert, aber er konvertiert mir das halt nicht.
Ziel ist: jedes einzelne Pixel in das pixelarray einzuspeichern.
-
Eine genaue Fehlerbeschreibung ist nie schlecht.
fread(pixelarray[i], sizeof(short), bildbreite,pFile);
Am einfachsten ist aber der Verzicht auf die Schleife und alles auf einmal holen.
fread(pixelarray, sizeof(short), bildbreite * bildhoehe, pFile);
Du brauchst ein C-Buch.
Du musst es dir auch durchlesen. Mehrmals
-
Danke schonmal für die dicke Hilfe.
Eigentlich progge ich viel und les auch viel durch in C und C++, allerdings zuviel frei gehabt in letzter Zeit und mit Dateien immer schon Probleme gehabt.Danke
Funzt nun alles.
-
Du hast Grundlegendes zu C nicht verstanden,
du weißt nicht was ein Array ist und wie man es gebraucht,
du weißt nicht, was ein Zeiger ist und wie man ihn gebraucht,
du weißt nicht, wie man korrekt aus Dateien liest,
du weißt nicht, wie man Strings mit scanf richtig liest,
du ignorierst die hier gegebenen Hinweise,
...Ich schließe mit meinem Vorredner an:
Du brauchst ein gutes C-Buch.
Du musst es dir auch durchlesen. Mehrmals, und wenigstens versuchen, zu verstehen.
-
Evtl. ist die Datei korrupt.
Nimst du die Originaldatei oder schon eine neue von dir?Das
fseek(pFile, 0*sizeof(char), SEEK_SET); //Dateianfang
ist nach einemfopen(filename,"rb");
sowieso gegeben
sizeof(char) ist immer noch 1pixelarray[i][j] == -1024;
ist ein Vergleich, keine zuweisung.Und das schreiben klappt so nicht, wenn du den Namen einer existierenden Datei eingibst.
Zudem schreibst du nur die rohen Bilddaten ohne Header.basti273 schrieb:
Ich les mir verdammt viel C und C++ durch
C und C++ sind zwei verschiedene Programmiersprachen.
basti273 schrieb:
und progge auch schon länger, aber Dateien sind immer wieder Probleme...
Welche Sprachen?