Translate project pages

This commit is contained in:
Kai Vogelgesang
2025-09-19 23:21:37 +02:00
parent 899add52f1
commit 50239a4d90
5 changed files with 160 additions and 159 deletions

View File

@@ -25,18 +25,18 @@
"id": "6ab69020", "id": "6ab69020",
"metadata": {}, "metadata": {},
"source": [ "source": [
"In diesem Projekt arbeiten wir mit Audio-Daten.\n", "In this project, we work with audio data.\n",
"Um das Einlesen möglichst unkompliziert zu halten, stellen wir die Eingabe in einem einfachen Format bereit:\n", "To facilitate reading it into your program, we provide the inputs in a simple format:\n",
"\n", "\n",
"```{admonition} Format\n", "```{admonition} Format\n",
"Die erste Zeile enthält $n$, die Anzahl der Samples ($0 \\leq n < 2^{32}$).\n", "The first line contains $n$, the number of samples ($0 \\leq n < 2^{32}$).\n",
"\n", "\n",
"Danach folgen $n$ Zeilen mit jeweils einem Sample $x$ als ganze Zahl ($-2^{15} \\leq x < 2^{15}$)\n", "Afterwards, $n$ lines follow, each with one sample $x$ as an integer ($-2^{15} \\leq x < 2^{15}$).\n",
"```\n", "```\n",
"\n", "\n",
"Die Abtastrate $f_S$ ist dabei 16640 Hz.\n", "The sampling rate $f_s$ is fixed at 16640 Hz.\n",
"\n", "\n",
"## Beispiel\n", "## Example\n",
"```\n", "```\n",
"10\n", "10\n",
"623\n", "623\n",
@@ -52,7 +52,7 @@
"```\n", "```\n",
"\n", "\n",
"```{note}\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", "Although the samples are given as integer numbers, for the rest of the project it makes sense to convert them into a floating point format at this point already.\n",
"```" "```"
] ]
}, },
@@ -61,32 +61,32 @@
"id": "cfcac6c9", "id": "cfcac6c9",
"metadata": {}, "metadata": {},
"source": [ "source": [
"# Visualisierung\n", "# Visualization\n",
"\n", "\n",
"In diesem Projekt kann es sehr hilfreich sein, sich nach jedem Arbeitsschritt das Ergebnis zu visualisieren.\n", "It can be helpful during this project to visualize the result after every step.\n",
"Das können wir zum Beispiel so tun:\n", "Wen can do this for example like this:\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", "- The signal contains 2 lines with 2080 pixels each per second. With $f_S = 16640\\text{Hz}$, we have 4 samples per 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", "- We take every 4th sample. For complex numbers, we calculate the magnitude $(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", "- We find $v_{min}$ and $v_{max}$, the smallest and largest values we obtained.\n",
" Dann skalieren wir jedes $v$ nach $255 \\cdot (v - v_{min}) / (v_{max} - v_{min})$.\n", " Then we scale each $v$ to $255 \\cdot (v - v_{min}) / (v_{max} - v_{min})$.\n",
" Damit bekommen wir einen Wert zwischen 0 und 255.\n", " The result is a value between 0 and 255.\n",
"- Diese Werte können wir jetzt als Pixel in einer Bilddatei abspeichern.\n", "- We can save these values as pixels in an image file.\n",
" Dazu können wir zum Beispiel das [](pgm-format) benutzen.\n", " To do this, we can use the [](pgm-format) for example.\n",
" \n", " \n",
"```{figure} img/reference/raw_full_scaled.webp\n", "```{figure} img/reference/raw_full_scaled.webp\n",
"---\n", "---\n",
"name: fig:raw_full.en\n", "name: fig:raw_full.en\n",
"---\n", "---\n",
"Visualisierung direkt nach dem Einlesen.\n", "Visualization, directly after reading the input.\n",
"Man kann das Bild fast schon erkennen, es ist aber noch sehr dunkel.\n", "The image can be discerned already, but it is quite dark.\n",
"```\n", "```\n",
"\n", "\n",
"```{figure} img/reference/raw_detail.webp\n", "```{figure} img/reference/raw_detail.webp\n",
"---\n", "---\n",
"name: fig:raw_detail.en\n", "name: fig:raw_detail.en\n",
"---\n", "---\n",
"Detailansicht.\n", "Detail view.\n",
"Hier sieht man deutliche vertikale Streifen, die von der Modulation auf den 2.4kHz Carrier kommen.\n", "We can clearly see vertical lines, stemming from the modulation onto the 2.4 kHz carrier.\n",
"```" "```"
] ]
} }

View File

@@ -5,7 +5,7 @@
"id": "e67c2a43", "id": "e67c2a43",
"metadata": {}, "metadata": {},
"source": [ "source": [
"# Frequenz-Shift" "# Frequency Shift"
] ]
}, },
{ {
@@ -17,7 +17,7 @@
"---\n", "---\n",
"name: fig:raw_waterfall.en\n", "name: fig:raw_waterfall.en\n",
"---\n", "---\n",
"Wasserfall-Diagramm. Wir können die beiden Kopien des Spektrums bei $\\pm2.4\\text{kHz}$ erkennen.\n", "Waterfall diagram. We can see both copies of the spectrum at $\\pm2.4\\text{kHz}$.\n",
"```" "```"
] ]
}, },
@@ -26,64 +26,64 @@
"id": "cbe50415", "id": "cbe50415",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Als ersten Schritt wollen wir die Kopie des Spektrums bei 2.4kHz \"auf die 0\" verschieben.\n", "As a first step, we want to shift the copy of the spectrum at 2.4 kHz to zero.\n",
"\n", "\n",
"Im Frequenz-Bereich können wir diese Verschiebung als eine Faltung mit einem Peak bei -2.4kHz darstellen.\n", "In the frequency domain, we can represent this shift as a convolution with a singular peak at -2.4kHz.\n",
"Wie können wir so einen Peak erzeugen?\n", "How can we create such a peak?\n",
"\n", "\n",
"Wir erinnern uns:\n", "We remember:\n",
"$\\sin(2\\pi f t)$ und $\\cos(2\\pi f t)$ hatten Peaks bei $\\pm f$.\n", "$\\sin(2\\pi f t)$ and $\\cos(2\\pi f t)$ have peaks at $\\pm f$.\n",
"\n", "\n",
"Genauer gesagt:\n", "To be precise:\n",
"```{math}\n", "```{math}\n",
"\\begin{align*}\n", "\\begin{align*}\n",
"\\sin(2\\pi f_0 t) \\,&\\circ\\!\\!-\\!\\!\\bullet\\, \\left\\{\\begin{array}{rcl}\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",
" -\\frac{1}{2}i &:& f = f_0 \\\\\n", " -\\frac{1}{2}i &:& f = f_0 \\\\\n",
" 0 &:& \\text{sonst} \\\\\n", " 0 &:& \\text{otherwise} \\\\\n",
"\\end{array}\\right. \\\\\n", "\\end{array}\\right. \\\\\n",
"\\cos(2\\pi f_0 t) \\,&\\circ\\!\\!-\\!\\!\\bullet\\, \\left\\{\\begin{array}{rcl}\n", "\\cos(2\\pi f_0 t) \\,&\\circ\\!\\!-\\!\\!\\bullet\\, \\left\\{\\begin{array}{rcl}\n",
" \\frac{1}{2} && f \\in \\{-f_0, f_0\\} \\\\\n", " \\frac{1}{2} && f \\in \\{-f_0, f_0\\} \\\\\n",
" 0 &:& \\text{sonst} \\\\\n", " 0 &:& \\text{otherwise} \\\\\n",
"\\end{array}\\right. \\\\\n", "\\end{array}\\right. \\\\\n",
"\\end{align*}\n", "\\end{align*}\n",
"```\n", "```\n",
"\n", "\n",
"Damit haben wir jeweils zwei Peaks.\n", "That is two peaks each\n",
"Wir können Sinus und Cosinus aber geschickt kombinieren so dass sich einer davon aufhebt:\n", "We can however combine sine and cosine so that one of them cancels out:\n",
"Wenn wir den Sinus mit $i$ multiplizieren bekommen wir:\n", "If we multiply the sine term with $i$, we get:\n",
"```{math}\n", "```{math}\n",
"i \\cdot \\sin(2\\pi f_0 t) \\,&\\circ\\!\\!-\\!\\!\\bullet\\, \\left\\{\\begin{array}{rcl}\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",
" 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", " 0 &:& \\text{otherwise} \\\\\n",
"\\end{array}\\right.\n", "\\end{array}\\right.\n",
"```\n", "```\n",
"Und wenn wir jetzt noch den Cosinus addieren:\n", "And if we now add the cosine term:\n",
"```{math}\n", "```{math}\n",
"\\cos(2\\pi f_0 t) + i\\sin(2\\pi f_0 t) \\,&\\circ\\!\\!-\\!\\!\\bullet\\, \\left\\{\\begin{array}{rcl}\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} = 0 && f = -f_0 \\\\\n",
" \\frac{1}{2} + \\frac{1}{2} = 1 &:& f = f_0 \\\\\n", " \\frac{1}{2} + \\frac{1}{2} = 1 &:& f = f_0 \\\\\n",
" 0 &:& \\text{sonst} \\\\\n", " 0 &:& \\text{otherwise} \\\\\n",
"\\end{array}\\right.\n", "\\end{array}\\right.\n",
"```\n", "```\n",
"Damit haben wir genau den Peak bei $f_0$.\n", "This yields exactly one peak at $f_0$.\n",
"\n", "\n",
"```{note}\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", "The expression $\\cos(x) + i\\sin(x)$ may be familliar from [Euler's formula](https://en.wikipedia.org/wiki/Euler's_formula).\n",
"```\n", "```\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", "To perform the frequency shift, we can simply multiply in the time domain (= each sample) with this function.\n",
"Dazu gehen wir so vor:\n", "We do this as follows:\n",
"- Für jedes Sample $s$ berechnen wir den aktuellen Zeitpunkt $t$.\n", "- For every sample $s$, we calculate the current time $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", " Since the sampling rate $f_S$ equals $16640\\text{Hz}$ we know that the duration in between two samples is exactly $1/16640\\text{s}$.\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", "- We then calculate $\\cos(2\\pi \\cdot -2400 \\cdot t) + i \\cdot \\sin(2\\pi \\cdot -2400 \\cdot t)$ and obtain a complex result $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", "- We multiply $s$ with this, resulting in $a \\cdot s + (b \\cdot s)i$, which we save as our new (complex) sample.\n",
"\n", "\n",
"```{note}\n", "```{note}\n",
"Für dieses Projekt reicht es theoretisch aus, komplexe Zahlen als Paare von jeweils zwei reelle Zahlen zu speichern.\n", "For this project, it is sufficient to represent complex numbers as pairs of two real numbers.\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", "But in some programming languages, there are explicit types for complex numbers, e.g., [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", "In Python, you can simply use `a + b * 1j`.\n",
"```" "```"
] ]
} }

File diff suppressed because one or more lines are too long

View File

@@ -5,7 +5,7 @@
"id": "f611b5a0", "id": "f611b5a0",
"metadata": {}, "metadata": {},
"source": [ "source": [
"# Synchronisierung" "# Synchronization"
] ]
}, },
{ {
@@ -13,45 +13,45 @@
"id": "0c5468d3", "id": "0c5468d3",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Aktuell sind die Samples noch als komplexe Zahlen dargestellt.\n", "Currently, the samples are still represented as complex numbers.\n",
"Um weiter mit ihnen arbeiten zu können, nehmen wir jeweils den Betrag:\n", "To continue working with them, we convert them to their magnitudes:\n",
"```{math}\n", "```{math}\n",
"s = a + bi \\mapsto |s| = \\sqrt{a^2 + b^2}\n", "s = a + bi \\mapsto |s| = \\sqrt{a^2 + b^2}\n",
"```\n", "```\n",
"\n", "\n",
"Hier eine Visualisierung des soweit verarbeiteten Signals:\n", "Here is a visualization of the signal as processed so far:\n",
"```{figure} img/reference/filtered_full_scaled.webp\n", "```{figure} img/reference/filtered_full_scaled.webp\n",
"---\n", "---\n",
"name: fig:filtered_full_scaled.en\n", "name: fig:filtered_full_scaled.en\n",
"---\n", "---\n",
"Gefiltertes Signal.\n", "Filtered signal.\n",
"Wir sehen dass die Sync-Streifen gebogen sind.\n", "We observe that the sync lines are bent.\n",
"```\n", "```\n",
"\n", "\n",
"Die Sync-Patterns markieren jeweils den Anfang einer Zeile.\n", "The sync patterns mark the beginning of each line.\n",
"Um das Bild \"gerade zu ziehen\" müssen wir sie finden.\n", "To \"straighten out\" the image, we have to find them.\n",
"\n", "\n",
"Dazu gehen wir so vor:\n", "We proceed as follows:\n",
"- Sync A hat das Pattern `000011001100110011001100110011000000000`.\n", "- Sync A has the pattern `000011001100110011001100110011000000000`.\n",
" Wir haben 4 Samples pro Pixel, also auch pro 0/1 im Pattern.\n", " We have 4 samples per pixel, and thus also per 0/1 in the pattern.\n",
" Dieses Pattern wollen wir suchen.\n", " We want to find this pattern.\n",
" Das funktioniert hier am besten, wenn wir sowohl das Pattern als auch die Samples in den Wertebereich zwischen $-1$ und $1$ skalieren.\n", " This is easiest if we scale both the pattern and our samples into the range between $-1$ and $1$.\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", " For every `0` in the pattern, we take four $-1$s, and for every `1` we take four $1$s.\n",
" Diese Sequenz von 39 * 4 = 156 Werten speichern wir als $p$.\n", " We save this sequence of 39 * 4 = 156 values as $p$.\n",
"- Jetzt betrachten wir Blöcke $x$ von 8320 Samples.\n", "- We now look at blocks $x$ of 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", " We find the minimum value $x_{min}$ and the maximum value $x_{max}$ within the block, and scale it such that the minimum is at $-1$ and the maximum at $1$:\n",
" ```{math}\n", " ```{math}\n",
" x[n] \\mapsto -1 + 2 \\cdot \\frac{x[n] - x_{min}}{x_{max} - x_{min}}\n", " x[n] \\mapsto -1 + 2 \\cdot \\frac{x[n] - x_{min}}{x_{max} - x_{min}}\n",
" ```\n", " ```\n",
"- Wir wollen die Position finden, die \"am meisten\" mit dem Pattern übereinstimmt.\n", "- We want to find the position that best matches the pattern.\n",
" Also iterieren wir über alle Startpositionen $i$ im Block, 0 bis (8320-156).\n", " To do this, we iterate over all positions $i$ in the block from 0 to (8320-156).\n",
" Für jede davon berechnen wir\n", " For each position, we compute the *correlation*\n",
" ```{math}\n", " ```{math}\n",
" z = \\sum_{n=0}^{156} x[i + n] \\cdot p[n]\n", " z = \\sum_{n=0}^{156} x[i + n] \\cdot p[n]\n",
" ```\n", " ```\n",
" Die Position bei der $z$ am größten ist, ist die mit der besten Übereinstimmung.\n", " The position with the highest $z$ value is the one that matches best.\n",
"- So können wir für jede Zeile die Anfangsposition finden.\n", "- This way, we can find the starting position of each line.\n",
" Von dort aus gehen wir in Viererschritten über die Samples, um die Pixelwerte für die Zeile zu erhalten." " From there, we can take every fourth sample to get the pixel values for this line."
] ]
} }
], ],

View File

@@ -5,7 +5,7 @@
"id": "af12be1c", "id": "af12be1c",
"metadata": {}, "metadata": {},
"source": [ "source": [
"# Ausgabe" "# Output"
] ]
}, },
{ {
@@ -13,30 +13,30 @@
"id": "8de61e70", "id": "8de61e70",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Wir haben jetzt Werte für die Pixel des Bildes, aber sie sind noch nicht im richtigen Bereich:\n", "We now have values for each pixel in the image, but these values are not yet in the correct range.\n",
"Sie müssen am Ende nämlich zwischen 0 und 255 liegen.\n", "At the end of the day, we want them to be between 0 and 255.\n",
"\n", "\n",
"Um sie zu richtig zu skalieren, verwenden wir den \"Space and Marker\" Teil des Bildformats:\n", "To scale them correctly, we use the \"space and marker\" part of the frame:\n",
"\n", "\n",
"```{figure} img/apt_frame_format.webp\n", "```{figure} img/apt_frame_format.webp\n",
"---\n", "---\n",
"name: fig:frame_format_output.en\n", "name: fig:frame_format_output.en\n",
"---\n", "---\n",
"Wieder das APT Bildformat.\n", "The APT frame format again.\n",
"Nach Sync A (39 Pixel breit) folgt ein 47 Pixel breiter Space mit schwarzen Pixeln.\n", "Sync A (39 pixels) is followed by a space of 47 black pixels.\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", "Similarly, sync B (39 pixel) in the second half is followed by a space of 47 white pixels.\n",
"```\n", "```\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", "The space following sync A has black pixels (except for the minute markers), and the space following sync b has white pixels.\n",
"Die Minute Marker ignorieren wir hier einfach :)\n", "We just ignore the minute markers :)\n",
"\n", "\n",
"Um die Pixelwerte in den richtigen Bereich zu skalieren können wir so vorgehen:\n", "We can scale the pixel values into the correct range like this:\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", "- We calculate the black level $v_b$ by computing the average (or [median](https://en.wikipedia.org/wiki/Median)) value of all pixels in the first space.\n",
"- Das gleiche tun wir für den Weiß-Level $v_w$ mit dem zweiten Space.\n", "- We do the same with the second space to get the white level $v_w$.\n",
"- Jetzt bilden wir jeden Pixelwert $v$ auf $(v - v_b) / (v_w - v_b)$ ab.\n", "- We now map every pixel value $v$ to $(v - v_b) / (v_w - v_b)$.\n",
"- Damit sind die Werte zwischen $v_b$ und $v_w$ in den Bereich zwischen 0 und 1 gewandert.\n", "- This has moved all values between $v_b$ and $v_w$ into the range between 0 and 1.\n",
"- Alle Werte kleiner als 0 oder größer als 1 werden auf 0 bzw. 1 begrenzt.\n", "- All values outside this range are clamped to 0 or 1 respectively.\n",
"- Jetzt müssen wir nur noch jeden Wert mit 255 multiplizieren." "- Finally, we have to multiply each value with 255."
] ]
}, },
{ {
@@ -45,22 +45,22 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"(pgm-format)=\n", "(pgm-format)=\n",
"## PGM-Format\n", "## PGM format\n",
"\n", "\n",
"```{note}\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", "Feel free to use a different format, or an image library like [Pillow](https://python-pillow.org/) or [SDL](https://www.libsdl.org/).\n",
"```\n", "```\n",
"\n", "\n",
"Um das fertige Bild in eine Datei zu schreiben, können wir zum Beispiel dieses sehr einfache Dateiformat benutzen:\n", "To write the final image into a file, we can use this very simple file format:\n",
"\n", "\n",
"```{admonition} Format\n", "```{admonition} Format\n",
"Die erste Zeile enthält den String `P2`.\n", "The first line contains the string `P2`.\n",
"\n", "\n",
"Die zweite Zeile enthält zwei positive Integer $w$ und $h$, die Breite $(w)$ und he $(h)$ des Bildes $(w = 2080, h \\approx 1400)$.\n", "The second line contains two positive integers $w$ and $h$, describing the width $(w)$ and height $(h)$ of the image $(w = 2080, h \\approx 1400)$.\n",
"\n", "\n",
"Die dritte Zeile enthält einen positiven Integer $v_{max} = 255$.\n", "The third line contains the positive integer $v_{max} = 255$.\n",
"\n", "\n",
"Danach folgen $h$ Zeilen mit jeweils $w$ Pixelwerten $v$ als Integer $(0 \\leq v \\leq v_{max})$.\n", "Afterwards, $h$ lines follow, containing $w$ integer pixel values $v$ $(0 \\leq v \\leq v_{max})$.\n",
"```" "```"
] ]
}, },
@@ -69,7 +69,7 @@
"id": "1ab1434e", "id": "1ab1434e",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Beispiel\n", "### Example\n",
"\n", "\n",
"```\n", "```\n",
"P2\n", "P2\n",
@@ -91,8 +91,8 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"```{note}\n", "```{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", "The PGM format only supports grayscale images, but there is also e.g. the PPM format for colored images.\n",
"[Hier](https://en.wikipedia.org/wiki/Netpbm) könnt ihr mehr dazu lesen.\n", "You can read more about it [here](https://en.wikipedia.org/wiki/Netpbm).\n",
"```" "```"
] ]
}, },
@@ -101,7 +101,7 @@
"id": "d16219b2", "id": "d16219b2",
"metadata": {}, "metadata": {},
"source": [ "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." "After saving the pixel values in such a file with a `.pgm` extension, we can look at them using a graphics program like [GIMP](https://www.gimp.org/)."
] ]
} }
], ],