====== Grundlagen der Bildverarbeitung ======
Dieser Abschnitt erklärt Grundbegriffe der digitalen Bildverarbeitung. Vorerst werden nur pixelbasierte Bilder betrachtet. Vektorgrafiken werden nicht behandelt.
Als erste Anwendung werden aus einem gegebenen Farbbild ROT-, GRÜN- und BLAU-Bilder, sowie Histogramme erstellt.
==== Pixelzahl eines Bildes ====
Jedes Bild (z.B. PNG oder JPEG) besitzt eine bestimmte Breite (X) und Höhe (Y). Diese beiden Angaben legen die Anzahl der Bildpunkte (Pixel) fest. Alle Bildpunkte zusammen bilden den Bildbereich:
**Pixelzahl eines Bildes = Breite · Höhe**\\
oder\\
**Bildbereich M = X · Y**
|{{ :inf:java:info_bild_grafik.png? |}}|
|Bildbereich M und Bildpunkte (Pixel). Der Farbwert w von jedem Pixel kann in einer Tabelle W gespeichert werden. W ist also die Menge aller Farbwerte.|
Jeder Bildpunkt besitzt einen Farbwert. Die Menge aller Farbwerte wird mit W bezeichnet.
Ein digitalisiertes Bild (b) ist eine Abbildung, bei der jeder Bildpunkt aus der Menge M des Bildbereiches einen Farbwert zugewiesen bekommt.
**Definiton**: Digitalisiertes Bild: b: M → W\\
M ist der Bildbereich\\
W ist die Menge aller Farbwerte
===== Das RGB System und Java =====
Eine Farbe ist durch ihre Anteile an den drei Grundfarben rot, grün und blau definiert. Dieses sogenannte RGB-System (Rot-Grün-Blau-System) basiert auf der additiven Farbmischung und ist nur eines von mehreren Farbmodellen, das für unsere Zwecke aber vollkommen ausreicht
Da jede der drei Grundfarben in 256 Stufen (0 - 255) dargestellt werden kann, lassen sich im RGB System ca. 16,7 Mio. verschiedene Farben definieren.
* 256 Rotwerte · 256 Grünwerte · 256 Blauwerte = 16 777 216 ≈ 16.7 Mio. Farben
Für Java gilt nun , dass jeder Bildpunkt ein Objekt (Variable) vom Typ Color ist.
Das folgende Codefragment erzeugt alle Farben die im Bild zu sehen sind:
|{{:inf:java:color-model-additive.png?|}}|
Color rot = Color(255,0.0);
Color green = Color(0,255.0);
Color blue = Color(0,0,255);
Color magenta = Color(255,0.255);
Color cyan = Color(0,255,255);
Color gelb = Color(255,255,0);
Color black = Color(0,0,0);
Color white = Color(255,255,255);
|
|Im RGB-System erhält jede Farbe einen bestimmten Anteil an rot, grün und blau.||
* ''Color( int r, int g, int b )'' erzeugt ein Color-Objekt mit den Grundfarben rot, grün und blau. Die Werte müssen im Bereich 0 bis 255 liegen. Jeder Farbwert ist also 1 byte = 8 bit groß.
* Die Methoden: int getRed(), int getGreen(), int getBlue() liefern jeweils den Rot-, Grün- und Blau-Anteil des Farbobjekts zurück. Jeder Farbwert ist dabei eine Zahl im Bereich von 0 bis 255.
* ''Color SCHWARZ = Color(0,0,0)''
* ''Color WEISS = Color(255,255,255)''
==== Color-Objekt ====
Ein **Color-Objekt** ist 32 Bit groß. Das letzte Byte, der α-Wert, ist die Transparenz (Deckkraft).
|@red:**Bit: 0-7 Rot-Wert Wertebereich 0-255**|@green:**Bit: 8-15 Grün-Wert Wertebereich 0-255**|@blue:**Bit: 16-23 Blau-Wert Wertebereich 0-255**|Bit: 24-31 Transparenz (Deckkraft)|
|Aufbau **java.awt.Color-Objekt** ||||
==== FSG-Bibliothek: Laden & Anzeigen eines Bildes ====
Das folgende Programm lädt ein Bild und zeigt es innerhalb eines Fensters an.
import de.informatics4kids.Picture;
import de.informatics4kids.PictureViewer;
public class Viewer {
public static void main(String[] args) {
// Bild erstellen und öffnen
Picture pic = new Picture("/home/student/testbild.jpg");
//Viewer verfügbar machen
PictureViewer viewer = new PictureViewer(pic.getPicture());
//Bild anzeigen
viewer.show();
}
}
|{{ :inf:java:hund.jpg? |}}|
|Das Bild aus dem obigen Programmbeispiel angezeigt mit der PictureViewer Klasse.|
===== Rot-, Grün-, und Blaubilder =====
Aus dem obigen Bild lässt sich ein Rotbild erzeugen, indem von jedem Pixel der Farbwert ermittelt und der Rotanteil bestimmt wird. Anschließend wird der Farbwert des Pixels durch ein Color-Objekt ersetzt, das nur den ermittelten Rotanteil enthält.
Das folgende Programm demonstriert dies Anhand des Pixels an der Position x = 4 und y = 5.
Der erste Pixel hat die Position (0,0) und befindet sich oben links im Bild.
import java.awt.Color;
import de.informatics4kids.Picture;
public class Main {
public static void main(String[] args) {
// testbild.jpg öffnen
Picture pic = new Picture();
pic.open("/home/student/Bilder/testbild.jpg");
// leere Kopie erzeugen
Picture rotBild = new Picture(pic.widthX(), pic.heightY());
// Farbe auslesen und neu erzeugen
Color farbe = pic.getColor(3, 4);
// nur rote Komponente einfügen!
Color rot = new Color(farbe.getRed(), 0, 0);
// Farbe setzen
rotBild.setColor(3, 4, rot);
}
}
Durchläuft man alle Pixel des Bildes und speichert immer nur eine Farbkomponente ab, erhält man Rot- ,Grün- oder Blaubilder. Auf diese Weise wurden die "bunten Hunde" erzeugt.
|{{ :inf:java:hunde.png? |}}|
|Rot- ,Grün- und Blaubilder enthalten jeweils nur einen Farbwert des Orginalbildes.|
===== Histogramme =====
Das Bild des roten Hundes besteht lediglich aus roten Farbwerten. Mit der Java Methode getRed() lässt sich der Farbwert jedes Bildpunktes (Pixel) auslesen und liefert einen Wert im Bereich von 0-255. Wird nun auf der X-Achse die Menge aller möglichen Farbwerte (0-255) und auf der dazugehörigen y-Achse jeweils, wie oft ein spezieller Farbwert im Bild gefunden wurde, aufgetragen, dann entsteht ein Histogramm.
|{{ :inf:java:histogramm.png? |}}|
|Histogramm des roten und grünen Hundes (siehe vorherigen Abschnitt). Auf der y-Achse lässt sich ablesen, wie oft ein einzelner Farbwert im jeweiligen Bild vorhanden ist. Wenn man alle Werte der Y-Achse durch den größten vorhandenen Wert teilt, dann liegen die Häufigkeiten zwischen 0 und 1. Dies nennt man Normierung.|
Ein Histogramm **h** eines Bildes **b** ist eine Abbildung von der Menge **W** des Farbbereichs auf das Intervall [0,1]. Derjenige Farbwert **(g)**, der am häufigsten vorkommt, erhält den Wert 1. Ein Farbwert, der überhaupt nicht vertreten ist, würde den Wert 0 zugewiesen bekommen.
**Definition**: Histogramm h
$$h:W \rightarrow [0,1]$$
* W: Farbbereich
* [0,1] Zahlenintervall von 0 bis 1.
mit
$$h(g)=\frac{\text{Menge aller Pixel mit dem Farbwert g}}{\text{Gesamtpixelzahl des Bildes}}$$