{ "cells": [ { "cell_type": "markdown", "id": "af12be1c", "metadata": {}, "source": [ "# Ausgabe" ] }, { "cell_type": "markdown", "id": "8de61e70", "metadata": {}, "source": [ "Wir haben jetzt Werte für die Pixel des Bildes, aber sie sind noch nicht im richtigen Bereich:\n", "Sie müssen am Ende nämlich zwischen 0 und 255 liegen.\n", "\n", "Um sie zu richtig zu skalieren, verwenden wir den \"Space and Marker\" Teil des Bildformats:\n", "\n", "```{figure} img/apt_frame_format.webp\n", "---\n", "name: fig:frame_format_output.en\n", "---\n", "Wieder das APT Bildformat.\n", "Nach Sync A (39 Pixel breit) folgt ein 47 Pixel breiter Space mit schwarzen Pixeln.\n", "Analog dazu sind in der zweiten Hälfte des Bildes der ebenfalls 39 Pixel breite Sync B und ein 47 Pixel breiter Space mit weißen Pixeln.\n", "```\n", "\n", "Der Sync A folgende Space hat (bis auf den Minute Marker) weiße Pixel, und der Space nach Sync B schwarze.\n", "Die Minute Marker ignorieren wir hier einfach :)\n", "\n", "Um die Pixelwerte in den richtigen Bereich zu skalieren können wir so vorgehen:\n", "- Wir berechnen das Schwarz-Level $v_b$ indem wir den Durchschnitt (oder den [Median](https://de.wikipedia.org/wiki/Median)) aller Pixelwerte im ersten Space nehmen.\n", "- Das gleiche tun wir für den Weiß-Level $v_w$ mit dem zweiten Space.\n", "- Jetzt bilden wir jeden Pixelwert $v$ auf $(v - v_b) / (v_w - v_b)$ ab.\n", "- Damit sind die Werte zwischen $v_b$ und $v_w$ in den Bereich zwischen 0 und 1 gewandert.\n", "- Alle Werte kleiner als 0 oder größer als 1 werden auf 0 bzw. 1 begrenzt.\n", "- Jetzt müssen wir nur noch jeden Wert mit 255 multiplizieren." ] }, { "cell_type": "markdown", "id": "436e60e1", "metadata": {}, "source": [ "(pgm-format)=\n", "## PGM-Format\n", "\n", "```{note}\n", "Wer möchte, kann natürlich gerne ein anderes Format benutzen, oder eine Bibliothek wie [Pillow](https://python-pillow.org/) oder [SDL](https://www.libsdl.org/).\n", "```\n", "\n", "Um das fertige Bild in eine Datei zu schreiben, können wir zum Beispiel dieses sehr einfache Dateiformat benutzen:\n", "\n", "```{admonition} Format\n", "Die erste Zeile enthält den String `P2`.\n", "\n", "Die zweite Zeile enthält zwei positive Integer $w$ und $h$, die Breite $(w)$ und Höhe $(h)$ des Bildes $(w = 2080, h \\approx 1400)$.\n", "\n", "Die dritte Zeile enthält einen positiven Integer $v_{max} = 255$.\n", "\n", "Danach folgen $h$ Zeilen mit jeweils $w$ Pixelwerten $v$ als Integer $(0 \\leq v \\leq v_{max})$.\n", "```" ] }, { "cell_type": "markdown", "id": "1ab1434e", "metadata": {}, "source": [ "### Beispiel\n", "\n", "```\n", "P2\n", "6 7\n", "255\n", " 0 6 12 18 24 30\n", " 6 240 235 230 30 36\n", "12 235 24 30 220 42\n", "18 230 235 220 42 48\n", "24 225 36 42 210 54\n", "30 220 215 210 54 60\n", "36 42 48 54 60 66\n", "```" ] }, { "cell_type": "markdown", "id": "c2c9a6b9", "metadata": {}, "source": [ "```{note}\n", "Das PGM-Format ist nur für Bilder in Graustufen, aber es gibt auch z.B. das PPM-Format für farbige Bilder.\n", "[Hier](https://en.wikipedia.org/wiki/Netpbm) könnt ihr mehr dazu lesen.\n", "```" ] }, { "cell_type": "markdown", "id": "d16219b2", "metadata": {}, "source": [ "Wenn wir unsere Pixelwerte so in eine Datei mit `.pgm`-Endung speichern, können wir sie mit einem Grafikprogramm wie z.B. [GIMP](https://www.gimp.org/) anschauen." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.13" } }, "nbformat": 4, "nbformat_minor": 5 }