PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [JAVA] Bildbearbeitung - Matritzen


Mosher
2010-11-19, 16:29:12
Tach.

Wollte schon mal vorarbeiten und unsere neue Programmieraufgabe lösen. Es geht dabei um Bildbearbeitung.

Ich soll über ein Bild, das ich bereits in Graustufen transformiert habe, eine Maske laufen lassen

public int[][] wendeMaskeAn (int[][] grau, int[][] maske, int hoehe, int breite) {

int [][] pixelKante = new int[hoehe][breite];

int farbsumme =0;
int farbe=0;

for(int i=1;i<hoehe-1;i++) {
for(int j=1;j<breite-1;j++) {

for(int iM=0;iM<3;iM++) {
for (int jM=0;jM<3;jM++) {
farbsumme = farbsumme+((grau[i-1+iM][j-1+jM])*maske[iM][jM])&255;

}
}
farbe = farbsumme/16;
pixelKante[i][j] = farbe;
}
}
return pixelKante;
}


Ich fange quasi, da es eine 3X3-Matrix ist beim Pixel (1|1) an und höre bei (Höhe-1|Breite-1) auf.

Das wird durch die beiden äußeren for-schleifen erreicht werden.

die beiden inneren sollen jetzt dem Pixel, den ich gerade betrachte, den Mittelwert aller umgebenden Farbwerte der umgebenden Pixel multipliziert mit der jeweiligen Position in der 3x3 Matrix, zuweisen.

in einer zweiten Methode, die schon funktionstüchtig ist, werden aus den Grauwerten wieder RGB-Werte gemacht und dann das Bild gezeichnet.

Laut Angabe soll ich den Filter {{1,1,1},{0,0,0},{-1,-1,-1}} verwenden, also einen Kantenfilter.

Leider erhalte ich immer ein fast schwarzes Bild mit einigen Schlieren darin.
Kann mir jmd. helfen?

zur Erklärung der Methode: grau[][] soll das 2D-Array der Pixel eines Graustufenbildes sein, maske[][] die 3x3-Maske, höhe und breite halt höhe und breite des bildes ^^

Neomi
2010-11-19, 16:43:14
1. Du solltest "farbsumme" zwei Schleifenebenen tiefer auf 0 initialisieren, also einmal pro berechnetem Pixel.

2. Du hast eine 3x3-Matrix, teilst aber durch 16. Aber auch durch 9 zu teilen wäre verkehrt. Die Summe der Werte in der Matrix ist 0, wahrscheinlich sollte also durch gar nichts geteilt werden. Wodurch geteilt werden soll, sollte eigentlich als Parameter mitgegeben werden, denn das hängt vom konkreten Anwendungszweck ab.

3. Was willst du mit dem &255 bezwecken? Ich kann mir nicht vorstellen, daß du das da wirklich haben willst. Du solltest stattdessen den fertigen Wert auf den gültigen Wertebereich clampen.

Mosher
2010-11-19, 16:47:31
1. Du solltest "farbsumme" zwei Schleifenebenen tiefer auf 0 initialisieren, also einmal pro berechnetem Pixel.

2. Du hast eine 3x3-Matrix, teilst aber durch 16. Aber auch durch 9 zu teilen wäre verkehrt. Die Summe der Werte in der Matrix ist 0, wahrscheinlich sollte also durch gar nichts geteilt werden. Wodurch geteilt werden soll, sollte eigentlich als Parameter mitgegeben werden, denn das hängt vom konkreten Anwendungszweck ab.

3. Was willst du mit dem &255 bezwecken? Ich kann mir nicht vorstellen, daß du das da wirklich haben willst. Du solltest stattdessen den fertigen Wert auf den gültigen Wertebereich clampen.


danke für die schnelle Antwort.

Die &255 sind dafür da, nur den Grauwert herauszufiltern (in der Angabe steht, wir sollen das so machen und nachher das ganze Array wieder auf RGB hochrechnen)

In der Angabe steht außerdem der Hinweis, dass aufgrund der Maske Werte > 255 und Werte < 0 auftreten könnten, was wir mit einer geeigneten Rechnung abfangen sollen.

Allerdings ist mir das noch etwas schleierhaft.

Naja ich probier jetzt mal, die Farbsumme weiter unten zu initialisieren


Edit: Hat tatsächlich was gebracht. Aber leider ist das Ergebnis immer noch nicht ganz stimmig.
@Neomi: Falls du noch Lust hast, mir zu helfen, würde ich dir mal die Angabe schicken. Vielleicht hab´ ich ja auch einfach nur was falsch verstanden.

Neomi
2010-11-19, 17:00:34
Die Maskierung mit 255 müßtest du vor der Multiplikation mit der Matrix machen, nicht danach. Die unpassenden Werte abfangen sollte so gehen:

farbe = farbsumme/divisor; // divisor ist ein Parameter von außen, sollte hier 1 sein
if (farbe < 0)
farbe = 0;
if (farbe > 255)
farbe = 255;
pixelKante[i][j] = farbe;

Wenn damit immer noch Probleme auftauchen, kannst du ja einfach die Aufgabe nennen oder, falls das nicht geht, mir eine PM dazu schicken. Ich werde da aber erst in ein paar Stunden wieder draufschauen können.

Mosher
2010-11-19, 17:13:20
aaaah, da war auch wieder ein Fehler.

Besten Dank, jetzt bin ich fast da, wo ich hinwollte.
Das mit dem Divisor klingt plausibel und die Abfrage ist ja auch simpel.

Ich dachte eher ich müsste alle Werte um (ax+b) verschieben oder so
Mein Ergebnis ist jetzt einfach nur noch zu dunkel im Vergleich zum Beispiel. aber wenn ich mir die vergangenen Aufgaben so ansehe, könnte das auch Absicht sein ;)

Besten Dank für die schnelle Hilfe

Gast
2010-12-01, 22:48:31
Und die Maske lautet tatsächlich [1 1 1][0 0 0][-1 -1 -1]? Der klassische Sobel Kantendetektor hat AFAIK [1 2 1][0 0 0][-1 -2 -1]. Dürfte aber nicht viel Unterschied machen...

Falls du noch durch etwas ungleich 1 dividierst aufpassen dass keine integer division passiert.

THEaaron
2010-12-02, 17:45:44
Hab in Java mal eine Klasse geschrieben mit der man eine Faltungsmatrix selbst angeben kann und diese dann über ein Bild in einem ImagePuffer bügelt. Ist wirklich kein schöner Code, aber falls du Interesse hast schick ich dir die Klasse gern per PN.

Mosher
2010-12-03, 18:09:04
Aah, hab gar nicht mitbekommen, dass ihr noch was gepostet habt.

Also das Programm hat dann doch funktioniert und ja, die Maske war 111 000 -1-1-1

Die Normierung erfolgte durch Pixel = (Pixel-minimum)*255/max-min