====== 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}}$$