Aus Datei lesen



  • So csollte es heißen:
    Du willst pixel5 bearbeiten, dann ist pixel3 eine Zeile Weiniger und 1 Spalte mehr.

    Du willst schärfen. Dann musst du die einzelnen Pixel anders bewerten (malnehmen).
    Sharpen ist

    -1 -1 -1
    -1  9 -1
    -1 -1 -1
    

    Und als Divisor 1.0

    Du kannst mit den Werten auch spielen

    -1 -1 -1
    -1 17 -1
    -1 -1 -1
    

    Und als Divisor 9.0

    Du solltest darauf achten, dass als Ergebnis 1.0 heraus
    Oberes Beispiel 8 *-1 + 9 = 1.0 / 1.0 = 1.0
    Unteres Beispiel 8 *-1 + 17 = 9.0 / 9.0 = 1.0

    PS Dein Beispiel war

    1 1 1
    1 1 1
    1 1 1
    

    Und als Divisor 9.0



  • Hmm,

    ich versuche grade dein Beispiel umzusetzen und les nochmal die Aufgabe durch. Ganz komme ich damit noch nicht klar.

    die Aufgabe lautet:

    Hier soll das Rauschen durch Mittelung eines Bildpunktes mit seinen
    8 Nachbarpunkten vermindert werden.
    Leider ist etwas verrauscht und
    muss mit einem Glättungs lter überarbeitet werden.

    Wenn das Ergebnis 1 wäre dann würde ich doch die Farbe des Pixels verändern oder?

    lg Zermy



  • Du verrechnest doch die Helligkeitswerte der (acht) Nachbarpixel mit dem mittleren Pixel.

    Wenn du die einfach addierst, wird der Punkt heller.
    Darum teilst du die Summe der Helligkeitswerte durch die Summe der Gewichtung.

    Je nachdem wie du sie verrechnest, ändert sich das Filter.
    Wenn du sie abziehst (* -1) und den mittleren überhöhst (*9) schärfst du das Bild.

    Wenn du die Parameter in einem 2D-Feld angibst, kannst du ganz einfach das Verhalten von dem Filter ändern, indem du das Feld änderst.

    Schau mal da: http://tavmjong.free.fr/INKSCAPE/MANUAL/html/Filters-Pixel.html oder http://lodev.org/cgtutor/filtering.html



  • Ok, du hast vollkommen recht!!!

    Ich versteh nur noch nicht ganz wie ich das mit dem sharpen machen muss. Will den Code ja auch verstehen.

    Bei mir hakt es aber bei dem Coden...

    Ich hab doch im Speicher keine x und y achse oder?

    Ich weiß irgendwie nicht wie ich loslegen soll, ich brauche 2 for schleifen eine für x und eine für y.

    Aber es soll ja nicht am Rand gestartet werden, sondern es sollen viele Pixel ausgelassen werden. Dann muss ja nach dem ausgelassenem Pixel 1 Spalte frei bleiben und dann 2 Spalten weiter springen... da ja die meisten pixel nur verglichen werden. Das gleiche dann für die Zeilen..

    lg Zermy



  • Bildbreite = 512
    Bildhoehe = 512
    
    Schleife über y (1 bis < Bildhoehe-1)  // 1 bis 510
      Schleife über x (1 bis < Bildbreite-1)
    
       Index = y * Bildbreite + x
    
       Mache_was_mit bild[Index]  
    ....
    

    Überleg dir noch etwas, damit du nicht mit geänderten Daten rechnest.
    Wenn du die 3. Zeile bearbeitest, stehen in der 2. schon manipulierte Werte.



  • Vielen Dank, für deine Hilfe!

    ich werd mich gleich dran machen.

    👍

    lg Zermy



  • Das heißt doch das ich die Zeile immer direkt wegspeichern und dann rückgänig machen muss, damit ich die neuen Werte für mein Bild hab und das rückgänig machen damit er nicht mit den geänderten werten rechnet, oder?

    lg Zermy



  • Zermy, du musst einfach beispielsweise mit nem short variablen "summe" folgendes machen:

    for(i=0; i<512;i++)
    {
    for(j=0; j<512;j++)
    {
    summe = (pixelarray[i][j].. und alle 8 Nachbarn) / 9;
    pixelarray[i][j] = summe;
    }
    }
    

    so hast du an der jeweiligen stelle wo du bist immer den mittelwert der Nachbarn mit in einem Punkt.
    Damit tastest du das ganze Bild ab und dann kommt schon wieder mit fwrite das ganze geschreibe 😉
    Dann sieht das Bild schon hübsch gefiltert aus.



  • Hey,

    danke für deine Antwort, aber ich will das Bild ja grade nicht in eine Matrix lesen xD

    Ich versuche das mal noch mit dem Speicher, ansonsten muss ich den Weg gehen!

    @ DirkB: ich bekomme die nicht hin...ich weiß nicht genau wie ich den Ausdruck unten bei dem Index in bild machen soll, kannst du mir da nochmal helfen?

    Bildbreite = 512;
    	Bildhoehe = 512;
    
    for(y=1;y<Bildhoehe-1;y++)					//Schleife über y (1 bis < Bildhoehe-1)  // 1 bis 510
    {
    	for(x=1;y<Bildbreite-1;x++)				//Schleife über x (1 bis < Bildbreite-1)
    	{
    			i=y*Bildbreite+x;				
    
    	}
    
    	bild[y*Bildbreite+x]+= ***************************;
    
    }
    

    lg Zermy



  • Hey,

    weiß noch jmd nen Rat?

    Ich möchte ungerne das ganze nochmal umschreiben und das Bild von Anfang an in einer Matrix behandeln, da ich es bald fertig haben muss! Im Speicher ist es ja auch ein Array ...

    lg Zermy



  • double pixel;
    Bildbreite = 512;
    	Bildhoehe = 512;
    
    for(y=1;y<Bildhoehe-1;y++)					//Schleife über y (1 bis < Bildhoehe-1)  // 1 bis 510
    {
    	for(x=1;y<Bildbreite-1;x++)				//Schleife über x (1 bis < Bildbreite-1)
    //          ^ Da muss ein x hin
    	{
    			i=y*Bildbreite+x;				
    
    	}  // Mit dieser klammer beendest du schon die x Schleife Weg damit
    
    //	bild[y*Bildbreite+x]+= ***************************;
    // Mach es doch erstmal per Hand
    	  pixel = (bild[(y  )*Bildbreite+(x)]-1024) * 9.0;  // Das eigentliche Pixel
    	  pixel += (bild[(y-1)*Bildbreite+(x-1)]-1024) * -1.0; pixel += (bild[(y-1)*Bildbreite+(x+0)]-1024) * -1.0; pixel += (bild[(y-1)*Bildbreite+(x+1)]-1024) * -1.0; 
    	  pixel += (bild[(y  )*Bildbreite+(x-1)]-1024) * -1.0; /* Hier wäre das Pixel an y+0,x+0 */                 pixel += (bild[(y  )*Bildbreite+(x+1)]-1024) * -1.0; 
    	  pixel += (bild[(y+1)*Bildbreite+(x-1)]-1024) * -1.0; pixel += (bild[(y+1)*Bildbreite+(x+0)]-1024) * -1.0; pixel += (bild[(y+1)*Bildbreite+(x+1)]-1024) * -1.0;
    	  pixel = pixel / 1.0 + 1024;
    
    //Jetzt musst du noch den gefilternen Bildpunkt wieder zurückschreiben.
    // :warning: Du musst die gefilterten Daten erst mal zwischenspeichern, und dann wieder zurückopieren
             gefiltert[y*Bildbreite+x] = pixel;          
    	}  // Das ist jetzt die Klammer die oben verkehrt war
    }
    // Hier jetzt das Array gefiltert nach bild kopieren.
    

    Wie das Array für gefiltert aussieht, wo du es herbekommst und wie du das zurückschreibst, darfst du selber überlegen.
    Das hast du aber alles schon mehr oder weniger in dem Programm gemacht.



  • ok, vielen Dank! Ohne deine Hilfe hätte ich das nicht hinbekommen!!!

    Echt sehr sehr nett, vielen Dank!

    lg Zermy



  • Hey,

    ich bekomms einfach nicht hin ... ich bin echt verzweifelt.Ich muss enorm viel aufholen in C ...

    den gefilterten bildpunkt geben ich doch so zurück

    bild[i]=pixel;
    

    Das mit dem Array und den gefilterten Werten ist für mich noch sehr komplex...

    Ich hab versucht mit einer einer for-Schleife die Punkte zwischen zu speichern, kommt aber leider nur Schnee raus 🙂

    Das mit dem Zwischenspeichern und Zurückkopieren versteh ich nicht und es wird sicher auch an dem Zurückkopieren des Arrays scheitern 😞

    lg Zermy



  • Gewöhnt euch doch mal daran, dass ihr in C für euch problematische Funktionalitäten kapseln könnt, solche 'Auslagerungen' nennt man auch 'Funktionen'.
    Schon mal gehört das Wort?
    Beim Design der Funktion muss man sich Gedanken über die Schnittstelle machen, d.h. welche Parameter gehen rein, welche gehen raus.

    Hier mal beispielhaft, ungetestet und ohne Fehlerbehandlung als Funktion 'konvertiere':

    unsigned short konvertiere(unsigned short pixel)
    {
    /* hier ist die eigentliche Aufgabenstellung ausgelagert worden,
       d.h. hier wurde Datei/Speicher/... usw. Randproblematiken weggekapselt
       und ihr könnt euch auf das eigentlich Problem konzentrieren */
    
      pixel = pixel - 1024; /* oder was auch immer ihr hier machen wollt/sollt */
      ...
      return pixel;
    }
    
    int main ()
    {
      FILE *f=fopen("bla.ima","r+b"); /* Lesen und Schreiben binär, evtl. noch auf unsigned short Alignment achten! (was das ist -- fragt euren Lehrer) */
      long lSize,x,y;
      unsigned char *puffer;
      unsigned short *p,(*pixel)[512]; /* Zeiger auf 'eine' 512er-Pixelzeile */
    
      fseek(f , 0L , SEEK_END);
      lSize = ftell(f);
      rewind(f);
    
      p = puffer = malloc(lSize);
    
      /* GANZE Datei einlesen in Pufferbereich */
      if( !fread(puffer,lSize,1,f) ) exit(1);
    
      /* suchen nach den 'magischen' Headerinfos und Zeiger auf Position 'dahinter' setzen */
      while( p[0]!=0x7FE0 && p[1]!=0x0010 ) ++p;
      /* p steht jetzt auf den 'magischen' Werten, jetzt noch Position 'dahinter' setzen */
      p+=2;
      /* jetzt steht der Zeiger p auf dem Beginn der Pixelmatrix und es kann losgehen */
    
      pixel=p; /* anonymen unsigned char/unsigned short Speicherbereich vorbereiten für 'pixelmatrix'-Durchlauf */
    
      /* hier einfach 512x512 pixelweise durchlaufen */
      for(y=0;y<512;++y)
      for(x=0;x<512;++x)
        pixel[x][y]=konvertiere(pixel[x][y]); /* und jeweils eine evtl. Konvertierung machen und konvertierten oder nicht konvertierten Wert immer zurückschreiben an originale Position */
    
      rewind(f); /* <-- vro Zurückschreiben des Dateiinhaltes muss der Deskriptor wieder an den Anfang */
      if( !fwrite(puffer,lSize,1,f) ) exit(1); /* ganzen Speicherbereich INKL. der evtl. konvertierten Pixel wieder zurückschreiben */
      fclose(f);
      free(puffer);
    
      return 0;
    }
    


  • Hey,

    danke!

    Ich werde das mal alles aufholen und nochmal von Grund auf neu lernen!

    Ich hab viele große Lücken aber muss nun am Ball bleiben!

    Danke nochmal für eure Hilfe. Ich werde sicher in Zukunft noch oft hier fragen 🙂 Ich werde mir dann aber auch gleich die bessere Struktur und einen guten Coding Style aneignen.

    lg Zermy



  • Eine doofe Frage habe ich aber noch:

    Wie mache ich das, dass ich es hinbekomme mit sscanf und sprintf einen Dateinamen einzulesen und diesen dann mit einem Anhang auszugeben.

    Egal welche Datei es sein soll.

    zB.:

    Eingabe:
    Leber.ima

    Ausgabe:
    Leber_bearbeitet.ima

    bei mir kommen immer sone Scherze wie Leber.ima_bearbeitet oder so raus.

    lg Zermy und schonmal ein schönes Wochenende!!!



  • Ein sscanf(Dateiname, "%[^.]%s", filename, extension); geht bei einfachen Dateinamen, scheitert aber bei relativen Angaben ("../Datei.ext")

    Da musst du wohl mit den Funktionen aus string.h rumspielen. z.B strrchr(Dateiname, '.')

    Dann hast du die Position vom . (wenn er vorhanden ist) und er muss rechts vom '\' bzw '/' sein.



  • Moin, kurze Frage, ich denke das die anderen hier auch in dem selben Studiengang sind, denn sonst hätten wir alle nicht die gleiche Aufgabe 😃

    Naja ich habe es noch etwas anders gelöst.... Jetzt habe ich den Witz im PC Pool vor Ort ging es, zu Hause jetzt nicht. Besonders fällt mir auf, in der Aufgabenstellung heißt es man öffnet die Datei "Kopf.IMA" und möchte als "Kopf_seg.IMA" speichern und wenn ich das eingebe dann kommt stack corrupt output Fehler, aber wenn ich alles andere eingebe klappt es. Ich habe fast das Gefühl es liegt am Unterstrich, weil K.IMA macht er ohne Probleme aber auch da hapert es irgendwie, denn wenn ich es im Programm angucke ist nicht alles draußen was sein sollte 😞

    #include <stdio.h>
    #include <string.h>
    
    void main()
    {
    	short vector[2]={0};
    	short bild[512][512];
    	int count = 0, i, x = 0, y = 0;
    	char input[10], output[10], eingabe[100]="C:\\PRP2\\", ausgabe[100]="C:\\PRP2\\";
    	FILE *fp;
    
    	printf("\n\nBitte geben Sie den Namen der Input-Datei ein! ");
    	scanf("%s", &input);
    	strcat(eingabe,input); // Eingabe ist der Pfad mit cat wird input hinten rangehangen
    	printf("%s\n\n", eingabe);
    
    	printf("\n\nBitte geben Sie den Namen der Output-Datei ein! ");
    	scanf("%s", &output);
    
    	while (strcmp(input,output) == 0) // Wird verglichen, damit nicht zwei Mal gleicher Name entsteht also Datei überschreibt
    	{
    		printf("\n\nDie Output-Datei darf nicht den gleichen Namen haben wie die Input-Datei! ");
    		scanf("%s", output);
    
    	}
    	strcat(ausgabe,output);
    	printf("%s\n\n", ausgabe);
    
    	fp = fopen(eingabe, "rb");
    	if(fp == NULL)
    	{
    		printf("File does not exist");
    	}
    	else
    	{
    		//printf("\n\nCT Reader\n");
    		while(!(vector[0]==0x7FE0&&vector[1]==0x0010)) // wichtig sind ja nur folgende Strings nach den gesucht werden muss
    		{
    			fread(vector, sizeof(short),2, fp);
    		}		
    		if(vector[0]==0x7FE0&&vector[1]==0x0010)
    		{			
    			fseek(fp, 4*sizeof(char)+sizeof(long), SEEK_CUR); 
    			fread(bild, sizeof(short),512*512, fp);
    
    			for(x=0;x<512;x++) // Short Matrix des Bildes wird eingelesen und die Punkte auf schwarz gesetzt
    			{
    				for(y=0;y<512;y++)
    				{
    					if(bild[x][y]==124 || bild[x][y]==1274)
    						bild[x][y] = 0;
    				}
    			}
    			fclose(fp);
    			fp = fopen(ausgabe, "wb"); // neue Datei wird geöffnet (falls nicht vorhanden neu angelegt)
    			fwrite(bild, sizeof(short),512*512, fp);
    			fclose(fp);
    		}
    
    	}
    }
    

    Warum jetzt output rumpöbelt und habe ich irgendwo noch was vergessen z.B. in der for Schleife weil wie gesagt irgendwie nicht alles "unnötige" auf schwarz gesetzt wird...



  • Aus wie vielen Zeichen besteht "Kopf_seg.IMA"
    Und wo willst du diesen Namen speichern?
    Wie viel Platz hast du dafür vorgesehen?

    Mach beim nächsten mal einen neuen Thread auf. Dieser ist seit zwei Jahren tot.



  • saschokkk schrieb:

    ...weil wie gesagt irgendwie nicht alles "unnötige" auf schwarz gesetzt wird...

    Wie stellst du das fest?
    Wie lautet die Aufgabe?


Anmelden zum Antworten