Aus Datei lesen
-
Hey,
Nun habe ich ein Resultat, welches mir ein gefiltertes Bild ausgibt. Ich habe das Programm noch so erweitert, dass man nun den Namen der Datei eingeben kann und der Pfad nicht mehr fest ist.
Vielen Dank nochmal für eure Hilfe und Unterstützung!!!
Ich kümmere mich jetzt erstmal ums Rauschen und dann um den Zoom
Evtl. hört ihr dann nochmal von mirIch werde aufjedenfall dabei bleiben und c programmieren!
for(x=0;x<512*512;x++) { short pixel; pixel = bild[i] - 1024; if((pixel<-900)||( pixel>250)) { pixel=-1024; bild[i]=pixel +1024; } i++; }
LG Zermy
-
Hey,
Ich bins nochmal... jetzt geht es darum aus dem gleichen Programm nur anderes Bild, die Pixel zu vergleichen um einen Glättungseffekt zu erzielen.
Das komplette Bild ist ja bereits im Speicher und das bild[i] steht am Anfang des zu lesenden Bereiches.
Die Frage ist nun nur ob ich das Bild in eine Matrix einlesen muss oder ob ich dies in dem Speicher lassen kann.
Ich verstehe noch nicht wie ich alle umliegenden Pixel erreichen soll, wenns im Speicher bleiben soll.
Wenn ich das pixel i hab dann muss ich ja nur um rechts und links das pixel davon zu erreichen, i+1 bzw. i-1 rechnen. Aber wie soll ich die dadrüber erreichen? Ich meine im Speicher wird dies doch auch in Zeilen und Spalten gespeichert also müsste man doch mit i+512 das pixel unter i erreichen oder sehe ich das falsch?
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)); printf("%d\n",i); printf("%d",lSize); for() { short pixel; short pixelnachbar; pixel = bild[i] - 1024; bild[i-1] bild[i+1] }
Im der nächsten Aufgabe soll dann ein Zoom erzeugt werden. Nicht mehr 512x512 sonder 256x256. Da müsste ich ja dann die umliegenden Pixel mit dem wert von einem Pixel bestücken.
Aber nun erstmal zu der Aufgabe 2
lg Zermy
-
Zermy schrieb:
Das komplette Bild ist ja bereits im Speicher und das bild[i] steht am Anfang des zu lesenden Bereiches.
Die Frage ist nun nur ob ich das Bild in eine Matrix einlesen muss oder ob ich dies in dem Speicher lassen kann.Kann so bleiben.
Und wenn du nochbild = bild+i; i = 0;
einfügst ist die ganze Sache evtl ein bisschen leichter handhabbar. Dann fängt der Bildindex immer wieder bei 0 an.
Dann brauchst du das i nicht mehr und kannst andere Zählvariablen nehmen.Zermy schrieb:
Wenn ich das pixel i hab dann muss ich ja nur um rechts und links das pixel davon zu erreichen, i+1 bzw. i-1 rechnen. Aber wie soll ich die dadrüber erreichen? Ich meine im Speicher wird dies doch auch in Zeilen und Spalten gespeichert also müsste man doch mit i+512 das pixel unter i erreichen oder sehe ich das falsch?
Ist richtig. Du musst nur an den Rändern aufpassen.
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)); printf("%d\n",i); printf("%d",lSize); bild = bild+i; i = 0; // <-- Hier eingefügt, dann sind ab bild nur Bilddaten for() { short pixel; short pixelnachbar; pixel = bild[i] - 1024; bild[i-1] bild[i+1] }
-
Hey,
danke für die schnelle Antwort DirkB!
Das Randproblem wollte ich lösen indem ich
for(x=1;x<511*511;x++)
Dann läuft er ja nicht bis zum Rand.
Aber mit dem durchgehen und vergleichen ist mir nicht ganz klar.
Ich brauche ja erstmal eine neue Variable in der ich short Werte ablegen kann.
short mittel;
in der for-Schleife muss ich ja nun
bild = bild+i; i = 0; // bild nur Bilddaten for(x=1;x<511*511;x++) // Randproblem gelöst { short pixel; pixel = bild[i] - 1024; pixel1=(bild[i]+bild[i-511]+bild[i+511]); i++; pixel2=(bild[i]+bild[i-511]+bild[i+511]); i++; pixel3=(bild[i]+bild[i-511]+bild[i+511]); mittel=(pixel1+pixel2+pixel3)/9; bild[i]=mittel+1024; }
Ich mache aber irgendwie ein Denkfehler ich hab ja sozusagen.
pixel1 pixel2 pixel3
pixel1 pixel2 pixel3
pixel1 pixel2 pixel2Addiere die dann und errechen mein mittel und schreib dann den Wert in Bild. Nehme mittel dann noch +1024 und dann sollte das doch gehen
?
Bekomme aber ein Speicher Fehler...
lg Zermy
-
Das
for(x=1;x<511*511;x++)
wird nicht funktionieren, da du so nur die letzten Punkte nicht hast.
Du musst zwei Schleifen verschachteln.Aus Zeile y und Spalte x berechnest du dann
i = y * 512 + x;
Überleg mal:
pixel1 pixel2 pixel3 pixel4 pixel5 pixel6 pixel7 pixel8 pixel9
Du willst pixel3 bearbeiten, dann ist pixel1 eine Zeile Weiniger und 1 Spalte mehr.
-
DirkB schrieb:
Du musst zwei Schleifen verschachteln.
Aus Zeile y und Spalte x berechnest du dann
i = y * 512 + x;
Klingt spannend!
DirkB schrieb:
Überleg mal:
pixel1 pixel2 pixel3 pixel4 pixel5 pixel6 pixel7 pixel8 pixel9
Du willst pixel3 bearbeiten, dann ist pixel1 eine Zeile Weiniger und 1 Spalte mehr.
In deinem Beispiel will ich doch pixel5 nehmen und mit den umliegenden vergleichen und allen den wert von pixel5 geben.
Vll. war glätten nicht richtig. Das Bild ist "verschwommen" und soll danach etwas klarer sein.
lg Zermy
-
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.0PS 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ättungslter ü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; }