Vorlesung Informatik 2 - Teil A: Java Kurs

8.5 Convolution Filter

Ein Convolution-Filter berechnet jeden Farbkanal eines Pixels neu, aus der Umgebung des Pixels.

Ein typisches Beispiel ist ein einfacher Weichzeichner, bei dem 9 Pixel in die Berechnung eingehen: das Pixel selbst sowie die acht umgebenden Pixel. Nehmen wir an, der Blau-Wert eines Pixels sei 4 und die umgebenden 8 Pixel haben die unten gezeigten Blau-Werte.   

     -------------                               -------------
     | 2 | 7 | 1 |                               | 2 | 7 | 1 |
     -------------           Weichzeichner       ------------- 
     | 3 | 4 | 6 |              -------->        | 3 | 5 | 6 |
     -------------                               -------------
     | 9 | 8 | 5 |                               | 9 | 8 | 5 |
     -------------                               -------------
   
Um das Bild weich zu zeichnen, berechnen wir jeden Farbkanal des mittleren Pixels  neu als Mittelwert aller Pixel in der Umgebung.

Ein Convolution Filter führt diese Operation anhand einer Matrix mit Koeffizienten durch, die auch Kern (Kernel) des Filters genannt wird. Für den Weichzeichner mit einem 3x3 Kern sieht die Matrix so aus:

     -------------------                              
     | 1/9 | 1/9 | 1/9 | 
     ------------------- 
     | 1/9 | 1/9 | 1/9 | 
     -------------------
     | 1/9 | 1/9 | 1/9 | 
     -------------------
Der neue Farbwert des mittleren Pixels wird also als  Summe der Produkte der Farbwerte der Umgebung mit dem jeweiligen Koeffizienten des Kerns gebildet.

In Java gibt es die Klasse ConvolveOp für Convolution  Filter. Ein 3x3 Weichzeichner wird wie folgt erzeugt:

	float[] k = { 1f/9f, 1f/9f, 1f/9f,
	              1f/9f, 1f/9f, 1f/9f,
		      1f/9f, 1f/9f, 1f/9f};
	Kernel kern = new Kernel(3,3,k);
ConvolveOp operator = new ConvolveOp(kern);

Oder:

      float[] k = new float[25];
      for int i=0;i<k.length;i++) k[i] = 1f/(float)l.length;

Und um den Filter auf ein Bild anzuwenden ruft man:

             operator.filter(bildAlt.getRaster(), bildNeu.getRaster());

wobei bildAlt und bildNeu vom Typ BufferedImage  sind.

Weitere Filter Kerne sind:
     ----------------                              
     |  0 | -1 |  0 | 
     ---------------- 
     | -1 |  5 | -1 |        Schärfungsfilter
     ----------------
     |  0 | -1 |  0 | 
     ----------------
     --------------                                        ----------------                         
     | 0 |  1 | 0 |                                        | -1 | -1 | -1 |
     --------------                                        ----------------
     | 1 | -4 | 1 |          Kanten-Filter (Laplace)       | -1 |  8 | -1 |  
     ---------------                                       ----------------
     | 0 |  1 | 0 |                                        | -1 | -1 | -1 | 
     ---------------                                       ----------------
     ---------------                              
     | -2 | -1 | 0 | 
     --------------- 
     | -1 |  1 | 1 |          Relief-Filter
     ---------------
     | 0  |  1 | 2 | 
     ---------------
     ----------------------                            
     | 1/16| 2/16 | 1/16  | 
     ----------------------
     | 2/16 | 4/16 | 2/16 |          Gauß-Filter (Weichzeichner)
     ----------------------
     | 1/16 | 2/16 | 1/16 | 
     ----------------------

Der Kern kann auch eine 5x5 oder 7x7 oder 9x9 Matrix sein, z.B. ist der folgende Filter ein höherwertiger Gauß-Weichzeichner:

        ------------------------                              
        |  1|  4  |  6 |  4|  1 | 
        ------------------------
        |  4 | 16 | 24 | 16 | 4 |         
   1    -------------------------
  ---   |  6 | 24 | 36 | 24 | 6 |        5x5 Gauß-Filter (Weichzeichner)
  256   ------------------------- 
        |  4 | 16 | 24 | 16 | 4 | 
        ------------------------- 
        |  1 |  4 |  6 |  4 | 1 | 
        -------------------------
        
Lehrvideo (YouTube)