Remove .ipynb_checkpoints from git
This commit is contained in:
parent
489ddd75b9
commit
899add52f1
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,4 @@
|
|||||||
_build
|
_build
|
||||||
.venv
|
.venv
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,116 +0,0 @@
|
|||||||
{
|
|
||||||
"cells": [
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"id": "d709b880",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"# Input"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"id": "5f40e11b",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"Here you can download the input files (right click / save as...):\n",
|
|
||||||
"* <a href=_static/2024-03-16-16k.in download>2024-03-16</a>\n",
|
|
||||||
"* <a href=_static/2023-04-20-16k.in download>2023-04-20</a>\n",
|
|
||||||
"* <a href=_static/2023-06-15-16k.in download>2023-06-15</a>\n",
|
|
||||||
"* <a href=_static/2024-03-14-16k.in download>2023-03-14</a>"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"id": "6ab69020",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"In diesem Projekt arbeiten wir mit Audio-Daten.\n",
|
|
||||||
"Um das Einlesen möglichst unkompliziert zu halten, stellen wir die Eingabe in einem einfachen Format bereit:\n",
|
|
||||||
"\n",
|
|
||||||
"```{admonition} Format\n",
|
|
||||||
"Die erste Zeile enthält $n$, die Anzahl der Samples ($0 \\leq n < 2^{32}$).\n",
|
|
||||||
"\n",
|
|
||||||
"Danach folgen $n$ Zeilen mit jeweils einem Sample $x$ als ganze Zahl ($-2^{15} \\leq x < 2^{15}$)\n",
|
|
||||||
"```\n",
|
|
||||||
"\n",
|
|
||||||
"Die Abtastrate $f_S$ ist dabei 16640 Hz.\n",
|
|
||||||
"\n",
|
|
||||||
"## Beispiel\n",
|
|
||||||
"```\n",
|
|
||||||
"10\n",
|
|
||||||
"623\n",
|
|
||||||
"-310\n",
|
|
||||||
"-273\n",
|
|
||||||
"3404\n",
|
|
||||||
"4745\n",
|
|
||||||
"655\n",
|
|
||||||
"-454\n",
|
|
||||||
"3463\n",
|
|
||||||
"3375\n",
|
|
||||||
"-5350\n",
|
|
||||||
"```\n",
|
|
||||||
"\n",
|
|
||||||
"```{note}\n",
|
|
||||||
"Die Werte der Samples sind hier zwar ganze Zahlen, aber für den Rest des Projekts ergibt es Sinn sie hier schon in Floating-Point Werte umzuwandeln.\n",
|
|
||||||
"```"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"id": "cfcac6c9",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"# Visualisierung\n",
|
|
||||||
"\n",
|
|
||||||
"In diesem Projekt kann es sehr hilfreich sein, sich nach jedem Arbeitsschritt das Ergebnis zu visualisieren.\n",
|
|
||||||
"Das können wir zum Beispiel so tun:\n",
|
|
||||||
"- Das Signal enthält 2 Zeilen mit je 2080 Pixeln pro Sekunde. Mit $f_S = 16640\\text{Hz}$ haben wir also 4 Samples pro Pixel.\n",
|
|
||||||
"- Wir nehmen jedes 4. Sample, falls es komplex ist berechnen wir den Betrag $(a + ib \\mapsto \\sqrt{a^2+b^2} =\\mathrel{\\vcenter{:}} v)$.\n",
|
|
||||||
"- Wir finden $v_{min}$ und $v_{max}$, den kleinsten bzw. größten so erhaltenen Wert.\n",
|
|
||||||
" Dann skalieren wir jedes $v$ nach $255 \\cdot (v - v_{min}) / (v_{max} - v_{min})$.\n",
|
|
||||||
" Damit bekommen wir einen Wert zwischen 0 und 255.\n",
|
|
||||||
"- Diese Werte können wir jetzt als Pixel in einer Bilddatei abspeichern.\n",
|
|
||||||
" Dazu können wir zum Beispiel das [](pgm-format) benutzen.\n",
|
|
||||||
" \n",
|
|
||||||
"```{figure} img/reference/raw_full_scaled.webp\n",
|
|
||||||
"---\n",
|
|
||||||
"name: fig:raw_full.en\n",
|
|
||||||
"---\n",
|
|
||||||
"Visualisierung direkt nach dem Einlesen.\n",
|
|
||||||
"Man kann das Bild fast schon erkennen, es ist aber noch sehr dunkel.\n",
|
|
||||||
"```\n",
|
|
||||||
"\n",
|
|
||||||
"```{figure} img/reference/raw_detail.webp\n",
|
|
||||||
"---\n",
|
|
||||||
"name: fig:raw_detail.en\n",
|
|
||||||
"---\n",
|
|
||||||
"Detailansicht.\n",
|
|
||||||
"Hier sieht man deutliche vertikale Streifen, die von der Modulation auf den 2.4kHz Carrier kommen.\n",
|
|
||||||
"```"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"celltoolbar": "Tags",
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
@ -1,112 +0,0 @@
|
|||||||
{
|
|
||||||
"cells": [
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"id": "e67c2a43",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"# Frequenz-Shift"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"id": "6482d25c",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"```{figure} img/reference/raw_waterfall.webp\n",
|
|
||||||
"---\n",
|
|
||||||
"name: fig:raw_waterfall.en\n",
|
|
||||||
"---\n",
|
|
||||||
"Wasserfall-Diagramm. Wir können die beiden Kopien des Spektrums bei $\\pm2.4\\text{kHz}$ erkennen.\n",
|
|
||||||
"```"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"id": "cbe50415",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"Als ersten Schritt wollen wir die Kopie des Spektrums bei 2.4kHz \"auf die 0\" verschieben.\n",
|
|
||||||
"\n",
|
|
||||||
"Im Frequenz-Bereich können wir diese Verschiebung als eine Faltung mit einem Peak bei -2.4kHz darstellen.\n",
|
|
||||||
"Wie können wir so einen Peak erzeugen?\n",
|
|
||||||
"\n",
|
|
||||||
"Wir erinnern uns:\n",
|
|
||||||
"$\\sin(2\\pi f t)$ und $\\cos(2\\pi f t)$ hatten Peaks bei $\\pm f$.\n",
|
|
||||||
"\n",
|
|
||||||
"Genauer gesagt:\n",
|
|
||||||
"```{math}\n",
|
|
||||||
"\\begin{align*}\n",
|
|
||||||
"\\sin(2\\pi f_0 t) \\,&\\circ\\!\\!-\\!\\!\\bullet\\, \\left\\{\\begin{array}{rcl}\n",
|
|
||||||
" \\frac{1}{2}i &∶& f = -f_0 \\\\\n",
|
|
||||||
" -\\frac{1}{2}i &:& f = f_0 \\\\\n",
|
|
||||||
" 0 &:& \\text{sonst} \\\\\n",
|
|
||||||
"\\end{array}\\right. \\\\\n",
|
|
||||||
"\\cos(2\\pi f_0 t) \\,&\\circ\\!\\!-\\!\\!\\bullet\\, \\left\\{\\begin{array}{rcl}\n",
|
|
||||||
" \\frac{1}{2} &∶& f \\in \\{-f_0, f_0\\} \\\\\n",
|
|
||||||
" 0 &:& \\text{sonst} \\\\\n",
|
|
||||||
"\\end{array}\\right. \\\\\n",
|
|
||||||
"\\end{align*}\n",
|
|
||||||
"```\n",
|
|
||||||
"\n",
|
|
||||||
"Damit haben wir jeweils zwei Peaks.\n",
|
|
||||||
"Wir können Sinus und Cosinus aber geschickt kombinieren so dass sich einer davon aufhebt:\n",
|
|
||||||
"Wenn wir den Sinus mit $i$ multiplizieren bekommen wir:\n",
|
|
||||||
"```{math}\n",
|
|
||||||
"i \\cdot \\sin(2\\pi f_0 t) \\,&\\circ\\!\\!-\\!\\!\\bullet\\, \\left\\{\\begin{array}{rcl}\n",
|
|
||||||
" i \\cdot \\frac{1}{2}i = -\\frac{1}{2} &∶& f = -f_0 \\\\\n",
|
|
||||||
" i \\cdot -\\frac{1}{2}i = \\frac{1}{2} &:& f = f_0 \\\\\n",
|
|
||||||
" 0 &:& \\text{sonst} \\\\\n",
|
|
||||||
"\\end{array}\\right.\n",
|
|
||||||
"```\n",
|
|
||||||
"Und wenn wir jetzt noch den Cosinus addieren:\n",
|
|
||||||
"```{math}\n",
|
|
||||||
"\\cos(2\\pi f_0 t) + i\\sin(2\\pi f_0 t) \\,&\\circ\\!\\!-\\!\\!\\bullet\\, \\left\\{\\begin{array}{rcl}\n",
|
|
||||||
" \\frac{1}{2} -\\frac{1}{2} = 0 &∶& f = -f_0 \\\\\n",
|
|
||||||
" \\frac{1}{2} + \\frac{1}{2} = 1 &:& f = f_0 \\\\\n",
|
|
||||||
" 0 &:& \\text{sonst} \\\\\n",
|
|
||||||
"\\end{array}\\right.\n",
|
|
||||||
"```\n",
|
|
||||||
"Damit haben wir genau den Peak bei $f_0$.\n",
|
|
||||||
"\n",
|
|
||||||
"```{note}\n",
|
|
||||||
"Den Ausdruck $\\cos(x) + i\\sin(x)$ habt ihr vielleicht schon mal in der [Eulerschen Formel](https://de.wikipedia.org/wiki/Eulersche_Formel) gesehen.\n",
|
|
||||||
"```\n",
|
|
||||||
"\n",
|
|
||||||
"Um den Frequenz-Shift durchzuführen, können wir also einfach in der Zeit-Domain (= auf den Samples) mit dieser Funktion multiplizieren.\n",
|
|
||||||
"Dazu gehen wir so vor:\n",
|
|
||||||
"- Für jedes Sample $s$ berechnen wir den aktuellen Zeitpunkt $t$.\n",
|
|
||||||
" Durch die Abtastrate $f_S = 16640\\text{Hz}$ wissen wir, dass der Zeitabstand zwischen zwei Samples genau $1/16640\\text{s}$ ist.\n",
|
|
||||||
"- Dann berechnen wir $\\cos(2\\pi \\cdot -2400 \\cdot t) + i \\cdot \\sin(2\\pi \\cdot -2400 \\cdot t)$ und erhalten einen komplexen Wert $a + bi$.\n",
|
|
||||||
"- Diesen multiplizieren wir mit $s$ und erhalten $a \\cdot s + (b \\cdot s)i$ und speichern ihn als neues, komplexes Sample.\n",
|
|
||||||
"\n",
|
|
||||||
"```{note}\n",
|
|
||||||
"Für dieses Projekt reicht es theoretisch aus, komplexe Zahlen als Paare von jeweils zwei reelle Zahlen zu speichern.\n",
|
|
||||||
"In manchen Programmiersprachen gibt es aber auch explizite Typen, um komplexe Zahlen darzustellen, z.B. [std::complex](https://en.cppreference.com/w/cpp/numeric/complex) in C++.\n",
|
|
||||||
"In Python kann man sie sogar einfach mit `a + b * 1j` erzeugen.\n",
|
|
||||||
"```"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
@ -1,79 +0,0 @@
|
|||||||
{
|
|
||||||
"cells": [
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"id": "f611b5a0",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"# Synchronisierung"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"id": "0c5468d3",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"Aktuell sind die Samples noch als komplexe Zahlen dargestellt.\n",
|
|
||||||
"Um weiter mit ihnen arbeiten zu können, nehmen wir jeweils den Betrag:\n",
|
|
||||||
"```{math}\n",
|
|
||||||
"s = a + bi \\mapsto |s| = \\sqrt{a^2 + b^2}\n",
|
|
||||||
"```\n",
|
|
||||||
"\n",
|
|
||||||
"Hier eine Visualisierung des soweit verarbeiteten Signals:\n",
|
|
||||||
"```{figure} img/reference/filtered_full_scaled.webp\n",
|
|
||||||
"---\n",
|
|
||||||
"name: fig:filtered_full_scaled.en\n",
|
|
||||||
"---\n",
|
|
||||||
"Gefiltertes Signal.\n",
|
|
||||||
"Wir sehen dass die Sync-Streifen gebogen sind.\n",
|
|
||||||
"```\n",
|
|
||||||
"\n",
|
|
||||||
"Die Sync-Patterns markieren jeweils den Anfang einer Zeile.\n",
|
|
||||||
"Um das Bild \"gerade zu ziehen\" müssen wir sie finden.\n",
|
|
||||||
"\n",
|
|
||||||
"Dazu gehen wir so vor:\n",
|
|
||||||
"- Sync A hat das Pattern `000011001100110011001100110011000000000`.\n",
|
|
||||||
" Wir haben 4 Samples pro Pixel, also auch pro 0/1 im Pattern.\n",
|
|
||||||
" Dieses Pattern wollen wir suchen.\n",
|
|
||||||
" Das funktioniert hier am besten, wenn wir sowohl das Pattern als auch die Samples in den Wertebereich zwischen $-1$ und $1$ skalieren.\n",
|
|
||||||
" Für jede `0` im Pattern nehmen wir also 4 mal die $-1$, und für jede `1` nehmen wir 4 mal die $1$.\n",
|
|
||||||
" Diese Sequenz von 39 * 4 = 156 Werten speichern wir als $p$.\n",
|
|
||||||
"- Jetzt betrachten wir Blöcke $x$ von 8320 Samples.\n",
|
|
||||||
" Wir finden Minimum $x_{min}$ und Maximum $x_{max}$ im Block, und skalieren so dass das Minimum bei $-1$ ist und das Maximum bei $1$:\n",
|
|
||||||
" ```{math}\n",
|
|
||||||
" x[n] \\mapsto -1 + 2 \\cdot \\frac{x[n] - x_{min}}{x_{max} - x_{min}}\n",
|
|
||||||
" ```\n",
|
|
||||||
"- Wir wollen die Position finden, die \"am meisten\" mit dem Pattern übereinstimmt.\n",
|
|
||||||
" Also iterieren wir über alle Startpositionen $i$ im Block, 0 bis (8320-156).\n",
|
|
||||||
" Für jede davon berechnen wir\n",
|
|
||||||
" ```{math}\n",
|
|
||||||
" z = \\sum_{n=0}^{156} x[i + n] \\cdot p[n]\n",
|
|
||||||
" ```\n",
|
|
||||||
" Die Position bei der $z$ am größten ist, ist die mit der besten Übereinstimmung.\n",
|
|
||||||
"- So können wir für jede Zeile die Anfangsposition finden.\n",
|
|
||||||
" Von dort aus gehen wir in Viererschritten über die Samples, um die Pixelwerte für die Zeile zu erhalten."
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
@ -1,129 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user