Tiefpassfilter
-
qt bietet überhaupt keine faltungs-methoden. qimage erlaubt allerdings zugriff auf die pixel, du könntest dir also selbst eine methode schreiben, die deine faltungsmatrix (den tiefpaß) kurz über das bild jagt.
wenn du dabei energieerhaltung und so zeug beachten musst, würd ich ne image library verwenden, die sowas unterstützt. vigra kann das beispielsweise (in der doc unter convolution nachgucken).
-
hi,
ja mein problem ist, dass ich als aufgabe hab funktionen einer library zu ersetzen...deswegen muss ich mir eine eigene funktion schreiben... im prinzip muss ich den ganzen tiefpass nur mit der lichtintensität der einzelnen pixel machen....und wie du schon sagtest...kann man ja durch qt auf die einzelnen values zugreifen.....
ich bräuchte nur eine art vorlage funktion...weil ich nicht so recht weiß wie ichs anstellen soll....
-
ich nehm mal an, bei deinem problem liegt der tiefpaß als quadratische matrix vor. gängig ist 3x3, größer geht aber auch, sollte nur ne ungerade katenlänge haben, damit er symmetrisch ist.
dann kannst du diese matrix einfach einmal über das bild jagen und die pixel entsprechend gewichten. wichtig ist dabei das normieren der pixel mit dem gewicht der matrix.
das gewicht ist die summe über die betragswerte der elemente der filter-matrix.
als beispiel:
QImage in_image; QImage out_image; ... float filter[] = {1,1,1, 0,0,0, -1,-1,-1}; // kantendetektor als beispielfilter float gewicht; // gewicht der matrix ... int offsets[][2] = {{-1,-1}, {0,-1}, {1,-1} ... {0,0} ... }; // die nachbarschaft offsets for(int y = 1; y < in_image.height-1; ++y) // randbehandlung: siehe kommentar for(int x = 1; x < in_image.width-1; ++x) { int gray_value = 0; // geht nur pro layer for(int o = 0; o < 9; ++o) gray_value += in_image.pixel(x + offsets[o][0], y + offsets[o][1]) * filter[o]; out_image.setPixel(x,y, gray_value/gewicht); }der rand wird in diesem beispiel ignoriert, bleibt also beispielsweise einfach schwarz. das ist durchaus üblich. alternativ kann der rand auch unendlich vergrößtert werden oder das gesamtbild als "donut" angenommen werden, also jeweils an den seiten verbunden.
das ganze ist im grunde recht simpel. probleme sind, wie erwähnt, die randbehandlung. außerdem muss aufgepasst werden, dass die intensität nicht aus dem gültigen bereich hinausläuft.
wie farbbilder behandelt werden, ist "geschmackssache". entweder wird aus den farblayern ein wert gebildet, gefiltert und wieder in farbwerte zerlegt. oder der filter wird auf alle farblayer einzeln angewendet und das bild anschliessend wieder zusammengeführt. die ergebnisse können durchaus verschieden sein.
das ganze kann als faltung mit der impulsantwort des filters angesehen werden und ist in der bildverarbeitung gängig.
allgemeiner in der signalverarbeitung wird aber lieber mit fourier transformationen rumhantiert.
-
kann ich die matrix freiwählen oder ist die durch irgendwelche kriterien auszuwählen???
das QImage, dass ich verwende hat 256 farben, aber mit der pixel abfrage bekommt man doch eh automatisch den value an einer bestimmten stelle, muss ich dann noch etwas zusätzlich machen?
ist für mich alles nicht so einfach, da ich noch nicht sehr lange programmiere.....
also sorry, wenn ich vielleicht ein paar "blöde" fragen stelle....aber danke auf jeden fall jetzt schon

-
was meinst du mit frei wählen? die größe ist beliebig. aber wenn die matrix eine gerade spalten/zeilen anzahl hat oder die spalten- ungleich der zeilenanzahl ist, dann wird das ganze nicht mehr ausgewogen.
der inhalt der matrix muss natürlich einem tiefpass entsprechen
ein tiefpaß in der bildverarbeitung ist eine glättung. dafür bietet sich ne gaußglocke an. die summe der elemente der matrix sollte dabei 1 entsprechen. da man dadurch "schlecht zu lesende" matrizen erhält, kann man alternativ auch einfach das ergebnis normieren. dies geschieht durch teilen des wertes durch die summe der matrixelemente.also beispielsweise die matrix
0 1 0 1 2 1 0 1 0hat die summe 6. man teilt also das ergebnis des mit dieser matrix "gefalteten" pixels durch 6.
das mit den farben ist so eine sache. das Qrgb besteht nicht aus komponenten, sondern ist ein int über den gesamten rgb farbraum. also von 0 (schwarz) bis 255^3 (weiss). teilt man so einen wert einfach, so bleibt er nicht "farbtreu". aus einem hellen grün könnte also beispielsweise ein dunkles rot werden und das will man eigentlich nicht.
wenn man das ganze komponentenweise macht, rgb vorausgesetzt, verändern sich die farben (theoretisch) nur in helligkeit und sättigung.
was meinst du mit 256 farben? indizierte werte durch eine farbtabelle? das ist fraglich. temporäres umwandeln in rgb wäre wohl der einfachere weg. wenn qimage das nicht eh schon automatisch macht.
-
das mit 256 farben, auf das komm ich nur dadurch, dass bei new qimage bei numColor= 256...aber könnten dass auch 256 graustufen sein???
-
noch ne frage...kann ich die gsl matrix verwenden für den lowpass filter??
würde dass dann ca. so aussehen?
QImage* qsplatdrr::Lowpassfilter_Image () { QImage* interMedImage = NULL; float gewicht; gsl_matrix* qsplatdrrFilterMatrix = gsl_matrix_alloc(3,3); uint Lowpass = gsl_matrix_get(qsplatdrrFilterMatrix,0,0)+gsl_matrix_get(qsplatdrrFilterMatrix,1,0)+ gsl_matrix_get(qsplatdrrFilterMatrix,0,1)+ gsl_matrix_get(qsplatdrrFilterMatrix,1,1)+ gsl_matrix_get(qsplatdrrFilterMatrix,2,1)+ gsl_matrix_get (qsplatdrrFilterMatrix,0,2)+ gsl_matrix_get(qsplatdrrFilterMatrix,2,2)+gsl_matrix_get(qsplatdrrFilterMatrix,3,0)+gsl_matrix_get(qsplatdrrFilterMatrix,0,3)+ gsl_matrix_get (qsplatdrrFilterMatrix,3,1)+ gsl_matrix_get(qsplatdrrFilterMatrix,1,3)+ gsl_matrix_get(qsplatdrrFilterMatrix,3,2)+ gsl_matrix_get(qsplatdrrFilterMatrix,2,3)+gsl_matrix_get(qsplatdrrFilterMatrix,3,3) /gewicht; for(uint y = 1; y < interMedImage -> height-1; ++y) { for(uint x = 1; x < interMedImage -> width-1; ++x){ uint value = 0; for(uint i = 0; i < 9; ++i){ value += interMedImage -> pixel(x + i, y + i) * Lowpass; interMedImage -> setPixel(x,y, value/gewicht); }}} return (interMedImage); }
-
Devil's Daughter schrieb:
das mit 256 farben, auf das komm ich nur dadurch, dass bei new qimage bei numColor= 256...aber könnten dass auch 256 graustufen sein???
kann sogar sehr gut angehen, ist das problemloseste für filter usw.
die gsl kenn ich leider nicht, aber welche matrix implementation du verwendest, spielt für die grundsätzlichkeit auch keine rolle. zugriff auf die pixel des bildes (qimage::pixel(x,y)) und zugriff auf die elemente der matrix (gsl_matrix_get(matrix, i,j)) sind alles, was grundsätzlich nötig ist.
also kurz: ja, die gsl matrix sollte es tun.
-
super danke!
irgendwie ist mir heute ein bisserl der knopf aufgegangen wie das ganze funktioniert

nur eine frage..wie bekomm ich diese fehlermeldungen noch weg..
for(uint y = 1; y < interMedImage -> height-1; ++y)
error: invalid use of member (did you forget the `&' ?)
for(uint x = 1; x < interMedImage -> width-1; ++x)
error: invalid use of member (did you forget the `&' ?)
-
du initialisierst dein interMedImage nicht:
QImage* interMedImage = NULL;da fehlt entweder eine zuweisung oder ein new. also beispielsweise
QImage* interMedImage = new QImage(640,480,Qt::IrgendEinFarbraum);aso, das problem ist ein anderes ^^ die zuweisung stört den compiler nicht weiter, das würd erst nen segfault zur laufzeit geben.
width und height sind private membervariablen. der zugriff erfolgt über methoden
interMedImage->width; // member variable, so nicht interMedImage->width(); // publich method, so gehts