Aus Datei lesen
-
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.imaAusgabe:
Leber_bearbeitet.imabei 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?
-
b) Bei jedem Punkt im Bild überlegen Sie sich, ob Sie den Bildwert lassen,
oder ob Sie ihn auf Null setzen, da er Luft oder Knochen entspricht.In dieser Aufgabe soll das Kopfbild bearbeitet werden, das im Verlauf einer
Schlaganfalldiagnose entstanden ist. Wie Sie sehen, gibt es auf dem Bild relativ
viel Luft (= alles, was einen CT-Wert kleiner als -900 HU hat) und
relativ viel Schädelknochen (= alles, was einen CT-Wert größer als 250 HU
hat). Weder die Luft noch der Schädelknochen sind in diesem Fall von Interesse,
so dass wir diese Daten auf -1024 HU setzen, also auf 0 im Datensatz,
so dass wirklich nur noch das Gehirngewebe angezeigt wird, das weiterverarbeitet
werden konnte.Deswegen meine For Schleife zum Einlesen der Matrix und danach die If Bedingung zum 0 setzen der Pixel, die eben außerhalb des "erlaubten" HU Bereichs sind.
Edit: Und hast natürlich Recht die Arrays müssen vergrößert werden
Aber sogar wenn die jetzt groß genug sind für Input und Output ist trotzdem Output corrupt...
-
saschokkk schrieb:
Aber sogar wenn die jetzt groß genug sind für Input und Output ist trotzdem Output corrupt...
Was meinst du damit? Die Arrays mit den Namen (input und output)? Die Dateien, deren Namen in den Arrays stehen?
Du setzt nur in zwei Fällen die Punkte auf 0. Dann wenn sie genau den Grenzwerten entsprechen.
In der Aufgabe stand sogar etwas von kleiner und größer.Beim Schreiben des Bildes hast du auch keine Headerinformationen mehr.
Ach und bei der Eingabe von Strings kommt in desn seltensten Fällen der Adressoperator zum Einsatz.
(Das & in Zeile 20 und 15 ist zuviel)