Aus Datei lesen



  • Oh, jetzt hast du alles weggemacht. 😞

    Ein Hinweis woran es gelegen hat wäre für andere evtl hilfreich.

    basti273 schrieb:

    Funzt nun alles.

    Das glaube ich nicht.



  • Hey Leute und erstmal frohe Ostern,

    vorweg mir fehlen die Basics und viel Routine in C wie ich mit dieser Aufgabe gemerkt hab.

    Ich fange nun an C von a bis z zu lesen, da ich das so nicht weiter machen kann.

    Ich hake schon ganz am Anfang und hoffe das ich hier evtl. Stück für Stück Hilfe bekomme. Das Schlimme ist, ich habe den Überblick über die Aufgabe verloren, bzw. mir fehlt allgemein der rote Faden.
    Ich möchte jetzt das im Speicher liegende Bild nach dem Hex-Code durchsuchen und dann meinen Zeiger dort platzieren, damit ich von dort aus 4 chars weiterspringen kann.

    #include <stdio.h>
    #include <stdlib.h>
    
    int main () {
      FILE * pFile;
      long lSize;
      char * buffer;
      size_t result;
      int i,n=0,x,y,z;
      short c;
      char hexcode[]={"0x7FE0,0x0010"};
    
      pFile = fopen ( "*********\\Kopf.IMA" , "rb" );
      if (pFile==NULL) {printf("Fehler");}
    
      // Anzeige der Filegröße
      fseek (pFile , 0 , SEEK_END);
      lSize = ftell (pFile);
      rewind (pFile);
    
      printf("Filesize:%ld \n",lSize);
    
      // Belegung des Speicher für den kompletten File
      buffer = (char*) malloc (sizeof(char)*lSize);
      if (buffer == NULL) {printf("Fehler");}
    
      // Kopieren des File in Speicher
      result = fread (buffer,1,lSize,pFile);
      if (result != lSize) {printf("Fehler");}
    
    	system("PAUSE");
    
      /* Die Datei ist nun komplett im Speicher :) */
    
      // Schließen und speicher freigeben
      fclose (pFile);
      free (buffer);
    
      return 0;
    
        }
    

    Über Hilfe wäre ich sehr dankbar, ich werde aber sicher oft und viel hier fragen. Da ich es nicht schaffe das Buch so schnell zu lesen wie die Aufgabe fertig sein sollte.

    lg Zermy



  • Das char hexcode[]={"0x7FE0,0x0010"}; ist ein String, damit kannst du erstmal wenig anfangen.
    Da kannst du ein short suchwerte[2] = {0x7FE0,0x0010}; nehmen.
    Damit kannst du direkt auf die Werte zugreife.

    Dann brauchst du noch einen Zeiger auf short, der auf den Anfang des buffers zeigt: short *bild; und bild = (short *)buffer;

    Dann kannst du mit einer Schleife durch bild gehen und vergleichen.
    Das kannst du mit Pointerarithmetik oder Arrayzugriff machen.

    for(i=0; i < (lSize / sizeof(short)-1); i++)
      if ((bild[i] == suchwerte[0]) && ...) break;
    

    Nach der Schleife kannst du i+=(4/sizeof(short)) machen und bist bei deinem gesuchten Index.
    Es sei denn die Suchwerte sind nicht vorhanden. Denn Fall musst auch noch abfangen.

    Was passiert, wenn malloc fehlschlägt?
    Du gibst "Fehler" aus und machst munter weiter.
    Ebenso bei fread.

    Das fclose kannst du auch gleich nach fread machen (wenn die komplette Datei gelesen wurde)



  • Hallo DirkB,

    vielen Dank für deine schnelle Antwort, ich werde dein geschriebenes mal umsetzen und versuche dabei richtig zu durchdringen. Ich poste dann hier meine Erfolg oder das was ich nicht schaffe.

    Um das mit den Fehlerausgaben richtig zu machen muss ich else anlegen richtig? Im Beispiel wird das so gemacht {fputs ("File error",stderr); exit (1);}

    Bis gleich

    Zermy



  • Durch das exit (1) wir das Programm an der Stelle beendet.
    Dann brauchst du kein else mehr.

    Achso, die ... musst du noch mit der zweiten Bedingung ausfüllen.



  • Ok xD danke {fputs ("File error",stderr); exit (1);} das ist die standart bibi für fehler soweit ich mich jetzt informiert hab. Das heißt man sollte diese benutzen und nicht mehr if else verzweigungen?

    und wo ich noch etwas hake vom Verständnis her ist hier:

    bild = (short *)buffer; 
    //hier deklarierst du den zeiger auf short der buffer 
    //heiß und wird nun die Adresse abgepeicher?
      for(i=0; i < (lSize / sizeof(short)-1); i++)
    // das lSize also die größe des   Bildes durch sizeof(short)-1 also die größe //von short das  -1 verstehe ich nicht, ziehste da 1 ab? Wenn ja warum?
    
      if ((bild[i] == suchwerte[0]) && ) break;
    	{fputs ("File error",stderr); exit (3);}
    
    // hinter dem && (bild[i] == suchwerte[1])? Da ich den zweiten Hex code ja auch //noch suchen muss?Jedoch steht i ja noch an der stelle von suchwert[0] und ich //müsste i doch weiter zählen lassen
    
      i+=(4/sizeof(short));
    //hier verstehe ich das so das ich nun an der stelle bin, ab der ich das Bild auf die -900HU oder <250 HU prüfen soll.
    

    lg Zermy



  • short *bild;  // Dies ist eine Definition von einem Zeiger auf short der bild heißt.
     bild = (short *)buffer; // Hier wird dem Zeiger ein Wert zugewiesen. (initialisiert)
    // bild zeigt jetzt auf den Anfang von buffer
    
      for(i=0; i < (lSize / sizeof(short)-1); i++)
    // lSize  ist die Größe in Byte. Wir brauchen aber die Größe in short.
    // Das -1 brauchst du, da du ja 2 short-Werte vergleichst und sonst zu weit liest
    
      if ((bild[i] == suchwerte[0]) && ) break;  // Das if ist nach dem break vorbei
    // Wie wärs mit  && (bild[i+1] == suchwerte[1])? 
    	{fputs ("File error",stderr); exit (3);} // Das wird immer ausgeführt
    // Warum willst du da dein Programm beenden  :confused: 
    
      i+=(4/sizeof(short));
    // Du willst doch 4 Byte weiterzählen. Und nicht 4 short
    
    // ab der ich das Bild auf die -900HU oder <250 HU prüfen soll. :confused: Davon hast du bis jetzt noch nichts gesagt.
    


  • Hey,

    ja hab mir in der Zeit, alles etwas genauer angeguckt und die IF auch schon erweiter. Das mit dem fputs war nen copy fehler... den hab ich auch beseitigt da das es sich sonst immer beendet.

    Ich wolle das Programm Schritt für Schritt aufbauen. Am Ende soll ein Bild entstehen wo der Knochen und die Luft herausgefiltert sind. Das heißt ab der Stelle wo wir jetzt sind,nach dem Hexcode und den 4 char zeichen die weitergespringen werden sollen.

    Muss das dann nicht
    i+=(4*sizeof(char));
    sein? Da ich 4 Chars weiter springen soll und nicht 4 Byte? Entschuldige für meine fehlende Information.

    Ich erläuftere nochmal kurz worum es in Aufgabe 1.1 geht.

    Kopf.IMA einlesen (später per CMD Abfrage, welches Bild man einlesen will)
    Jeden Bildpunkt vergleichen ob er Luft oder Knochen ist und in dem Fall auf 0 oder 1 setzen.
    Dazu muss ich nun jeden Punkt abfragen ob er x<-900HU(Luft) oder x>250HU(Knochen)
    das segmentierte Bild abspeichern(später per CMD Abfrage unter welchem Namen das Bild gespeichert werden soll)

    z.B
    Bitte geben SIe den namen der Input-Datei ein!
    Kopf.IMA
    Bitte geben Sie ein unter welchem Namen der Output gespeichert werden soll?
    Kop_seg.IMA
    Erfolgreich gespeichert oder Fehler.

    Ich hoffe ich konnte etwas Klarheit schaffen.

    lg Zermy



  • Zusatz:

    Zunächst kommt der so genannte Header der Datei, der eine
    Menge an anderen Informationen enthält (um die wir uns NICHT kümmern)
    und auch eine variable Größe 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, müssen noch vier char-Daten
    übersprungen werden, dann kommt als long die Anzahl der Bildpunkte und dann
    beginnen die Bilddaten (nachzulesen im DICOM-Standard). Die Größe der Bilder
    ist (bei der Computertomographie) 512 x 512 und die Bilddaten sind als short-
    Variablen gespeichert. Die Skala der möglichen Daten in der Datei beträgt also
    0 bis 4095. Diese Werte sind nicht direkt die CT-Werte: CT-Werte reichen von -
    1024 HU bis +3071 HU, von den Werten in der Datei müssen also 1024 abgezogen
    werden, um die tatsächlichen CT-Werte zu erhalten.

    lg Zermy



  • Der Index beim Array zählt schon um die richtige Anzahl Bytes weiter.

    char byte[20];
    short word[10];
    int i;
    
    for (i=0;i<10;i++)
      printf("Adresse von byte[%d]: %p und word[%d]: %p\n", i, &byte[i], i, &word[i]);
    

    Kannst du da sehen: http://codepad.org/9500XQz4
    Du siehst, das die Adresse von byte immer um 1 weitergeht, die Adresse von word dagegen um 2.

    Beispiel Hausnummern: rechts gerade, links ungerade. Du gehst auf der rechten Seite und sollst 4 Nummern weitergehen (von der 40 zur 44). Dann musst du doch nur 2 Häuser weiter (erst 42 dann 44).

    Darum musst du durch die größe deines Feldtyps teilen.

    Das ganze gilt auch dann, wenn du mit Pointern arbeitest. Der Compiler weiss dass du einen Zeiger auf short hast und rechnet entsprechend um.



  • Ah ok, danke für das Beispiel.

    Das mit den Hausnummer ist ein guter Vergleich.

    Ich sitze im Moment daran nun zu filtern... ich muss doch jetzt von den short werten erstmal 1024 abziehen damit ich dann meine werte hab die ich filtern kann.

    aber lSize ist ja nicht die anzahl der short zeigen sonder aller oder?



  • Wenn ich das richtig sehe, ist lSize die Dateigröße in Byte mit mit Header und noch anderen Informationen.

    Du hast 512*512 short.

    bild = bild+i;  // Bild zeigt jetzt auf die eigentlichen Bilddaten
    //Und dann
    for(i=0;<i<512*512;i++)
    {
      bild[i] = was du willst;
    }
    


  • Ok das Bild sieht schonmal anders aus, aber falsch xD die rechte seite ist sozusagen links angehängt. Der Compiler sagt ich überschreite meinen Speicher.
    Die while schleife ist für die Dateiausgabe. Das er es umspeichert.

    Was ich wohl noch gar nicht durchblickt habe ist das durchsuchen im Speicher.
    Ich meine in den short Werten sind doch meine CT-Werte gespeichert oder verstehe ich das falsch und ich muss doch 1024 short werde abziehen damit ich die richtige Anzahl von Werten habe.Ich will den wert von i auf 0 setzen wenn der zeiger an der richtigen Stelle ist. Aber das mit der Zeiger Programmierung ist ein riesen Thema, das muss ich noch oft lesen und viel rumprobieren...

    bild = (short *)buffer; 
      for(i=0; i < (lSize / sizeof(short)-1); i++)
      if ((bild[i] == suchwerte[0]) && (bild[i+1] == suchwerte[1])  ) break;
    
      i+=(4/sizeof(short));
    
    	lSize=result-sizeof(short)*(1024/4);
      printf("Filesize:%ld \n",lSize);
    
      for(x=0;x<lSize;x++)
      if(i =-900 || i>250)
      {
    	  i=0;
    
      }
    
          }
    
          while(!feof(pFile)) {
    
              ch = fgetc(pFile);
    
              fputc(ch, output);
    
          }
    


  • Die 1024 haben etwas mit dem Wert des Bildpunktes zu tun, nicht mit dem Index.



  • hmm, ist echt schwer alles nachzuvollziehen, wenn grade die Zeiger und die Arrays nicht so klar sind.

    Das Bild ist doch im Speicher und du hast mich an die richtige Stelle im Speicher gelenkt. Nun muss ich doch nur short für short auslesen und den Wert - 1024 rechnen? So versteh ich das und dann vergleichen ob der Wert größer oder kleiner ist.

    lg Zermy



  • Zermy schrieb:

    Das Bild ist doch im Speicher und du hast mich an die richtige Stelle im Speicher gelenkt. Nun muss ich doch nur short für short auslesen und den Wert - 1024 rechnen? So versteh ich das und dann vergleichen ob der Wert größer oder kleiner ist.

    Richtig, nur hat dein Codebeispiel von 15:14 Uhr damit nichts zu tun.

    Bei bild[i] steht ein Wert von dem Bild.

    short pixel;
    
     pixel = bild[i] - 1024; // dann steht in pixel der geändert Wert.
    


  • Ok, sorry der code klemmt sehr bei mir.

    Und die einzelnen Pixel vergleiche ich nun mit fgetc?

    lg Zermy



  • Wieso kommt denn jetzt fgetc ins Spiel? Was soll das denn einlesen?

    Vorhin hast du irgendetwas von "x<-900HU(Luft) oder x>250HU(Knochen) " geschrieben.
    Ich nehme an das sollen deine Grenzwerte sein. Damit musst du rechnen.



  • Da in Pixel jetzt mein geänderter wert steht muss ich Pixel auf <-900 || >250 prüfen, wenn ein der fall ist auf 0 setzen. Wenn das nicht der Fall ist weiter machen.

    Sehe ich das richtig? Und das wäre dann ne IF Anweisung oder?

    lg Zermy



  • Ja.

    Aber das zurückschreiben in das Array nicht vergessen.

    Man kann das Ganze dann aber noch zusammenfassen.


Anmelden zum Antworten