Update README.md
This commit is contained in:
parent
fe2ced28ff
commit
342daba79a
1 changed files with 148 additions and 414 deletions
562
README.md
562
README.md
|
|
@ -1,425 +1,159 @@
|
|||
text
|
||||
# IMX500 Object Detection GUI (OOP)
|
||||
# IMX500-Object-Detection-UI
|
||||
Eine interaktive, didaktische Anwendung für den Raspberry Pi 4/5 mit der Sony IMX500 AI Camera. Diese Software visualisiert Schritt für Schritt wie Objekterkennung funktioniert. Von der Rohdatenerfassung bis zum fertigen Ergebnis.
|
||||
|
||||
Eine modulare, objektorientierte Python-Anwendung, die den Sony IMX500 auf dem Raspberry Pi nutzt, um Objektdetektion in einer didaktisch aufbereiteten, schrittweisen Pygame-GUI zu visualisieren. Die Anwendung ist so strukturiert, dass Lesbarkeit, Wartbarkeit und Erweiterbarkeit im Vordergrund stehen (OOP, klare Verantwortlichkeiten, modulare Architektur, Typannotationen, Docstrings, sprechende Namen). [web:410][web:415][web:418]
|
||||
Die Anwendung bietet zwei Lernniveaus ("Schüler:innen" und "Student:innen") und ist für den Einsatz auf Messen, in Schulen oder Universitäten konzipiert.
|
||||
|
||||
---
|
||||
## 🚀 Features
|
||||
|
||||
## Überblick
|
||||
1. **Live-Objektdetektion:** Nutzt den Hardware-Beschleuniger des IMX500 Sensors.
|
||||
|
||||
Diese Anwendung demonstriert:
|
||||
2. **Zwei Lern-Niveaus:**
|
||||
|
||||
* **Schüler:** 4 vereinfachte Schritte, spielerischer Zugang.
|
||||
|
||||
* **Student:** 7 detaillierte Schritte mit technischer Tiefe (Pre-Processing, Tensoren, NMS).
|
||||
|
||||
- Live-Objektdetektion mit dem IMX500-Sensor (über Picamera2). [web:397][web:403]
|
||||
- Einfrieren eines Frames und Analyse in **4 Schritten**:
|
||||
1. Vorverarbeitung (Originalbild + Pixel-Grid, „RGB Pixel“-Badge).
|
||||
2. Threshold-/Binarisierungsansicht.
|
||||
3. Merkmalsextraktion (Kanten/Konturen mit Sobel).
|
||||
4. Lokalisierung (Bounding Boxes + Top‑3 Labels mit Score).
|
||||
- Darstellung in einer minimalen, fullscreen Pygame-GUI. [web:396][web:405]
|
||||
3. **Interaktiver Workflow:**
|
||||
|
||||
* *Live-Modus:* Echtzeit-Erkennung.
|
||||
|
||||
* *Analyse-Modus:* Einfrieren eines Bildes und schrittweise Durchleuchtung der KI-Pipeline.
|
||||
|
||||
Die komplette Logik ist in Klassen gekapselt, um eine saubere Trennung von **Hardware**, **Datenmodellen**, **Bildtransformationen**, **Rendering** und **Steuerlogik** zu erreichen.
|
||||
4. **Pixel-Inspektor:** In Schritt 1 können einzelne Pixel mit der Maus untersucht werden (RGB-Werte), um das Konzept der "Matrix" zu verdeutlichen.
|
||||
|
||||
---
|
||||
5. **Gate-Animationen:** Zwischen den Analyseschritten werden animierte Erklärungen (Bildsequenzen) abgespielt.
|
||||
|
||||
## Projektstruktur
|
||||
6. **Bilingual & Audio:** Vollständig in Deutsch und Englisch verfügbar, inklusive Sprachausgabe für Erklärtexte.
|
||||
|
||||
7. **Didaktische Visualisierung:**
|
||||
|
||||
* Simulation von Auflösungsreduzierung (Pixelation).
|
||||
|
||||
* Visualisierung von Feature-Maps (Sobel-Filter).
|
||||
|
||||
* Darstellung von Bounding Boxes und Confidence Scores.
|
||||
|
||||
## 🛠 Hardware-Voraussetzungen
|
||||
|
||||
* **Raspberry Pi 4 oder 5**
|
||||
|
||||
* **Betriebssystem:** Raspberry Pi OS **Bookworm (64-bit)** (Desktop-Version empfohlen für GUI).
|
||||
|
||||
* **Kamera:** Raspberry Pi AI Camera (Sony IMX500).
|
||||
|
||||
* **Display:** Monitor + Maus/Tastatur.
|
||||
|
||||
* **Audio:** Lautsprecher oder Kopfhörer (für die Sprachausgabe).
|
||||
|
||||
## 📦 Installation
|
||||
|
||||
1. **Repository klonen / Dateien kopieren:**
|
||||
|
||||
```bash
|
||||
git clone https://github.com/watsonove/IMX500-Object-Detection-UI/
|
||||
```
|
||||
|
||||
Stelle sicher, dass alle Projektdateien (`app.py`, `detector.py`, `steps.py`, Ordner `ui/` und `assets/`) vorhanden sind.
|
||||
|
||||
2. **Abhängigkeiten installieren:**
|
||||
|
||||
Alle Befehle werden im Terminal ausgeführt.
|
||||
|
||||
Das System benötigt Python 3, `picamera2` (vorinstalliert auf Bookworm) und `pygame`, sowie die IMX500 firmware `imx500`.
|
||||
|
||||
Zuerst sicher gehen, dass der Raspberry PI die aktuelle Software hat:
|
||||
|
||||
```bash
|
||||
sudo apt update && sudo apt full-upgrade
|
||||
```
|
||||
|
||||
Dann die Abhängigkeiten installieren:
|
||||
|
||||
```bash
|
||||
sudo apt install python3-libcamera python3-kms++ python3-pygame
|
||||
```
|
||||
|
||||
Sowie
|
||||
|
||||
```bash
|
||||
sudo apt install imx500-all
|
||||
```
|
||||
|
||||
Falls numpy fehlt:
|
||||
|
||||
```bash
|
||||
sudo apt install python3-numpy
|
||||
```
|
||||
|
||||
Nachdem du nun die Voraussetzungen installiert hast, starte den Raspberry Pi neu:
|
||||
|
||||
```bash
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
3. **Assets prüfen:**
|
||||
|
||||
Stelle sicher, dass die Ordnerstruktur korrekt ist (siehe unten "Projektstruktur"). Besonders wichtig sind die Bildsequenzen in `assets/schritt_X_experte/`.
|
||||
|
||||
## ▶️ Starten der Anwendung
|
||||
|
||||
Starte die Anwendung über das Terminal. Du musst den Pfad zu deiner Model-Datei angeben (z. B. ein MobileNet oder EfficientDet Modell, das für den IMX500 kompiliert ist).
|
||||
|
||||
```bash
|
||||
|
||||
python3 app.py --model=/usr/share/imx500-models/imx500_network_ssd_mobilenetv2_fpnlite_320x320_pp.rpk
|
||||
|
||||
```
|
||||
|
||||
## 🎮 Steuerung
|
||||
|
||||
|
||||
Die Anwendung ist für Tastatur- und Mausbedienung optimiert.
|
||||
|
||||
| Taste / Aktion | Funktion |
|
||||
| :----------------- | :---------------------------------------------------------------------- |
|
||||
| **LEERTASTE** | **Freeze / Unfreeze:** Wechselt zwischen Live-Kamera und Analyse-Modus. |
|
||||
| **ENTER** | **Weiter:** Geht zum nächsten Schritt oder bestätigt das "Gate". |
|
||||
| **BACKSPACE** | **Zurück:** Geht zum vorherigen Schritt oder zurück zum Gate. |
|
||||
| **Mausklick** | Bedienung der UI-Buttons (Sprache, Home, Audio, Level-Wahl). |
|
||||
| **Mausbewegung** | Im "Schritt 1" (Analyse): Zeigt RGB-Werte unter dem Mauszeiger an. |
|
||||
| **Q** oder **ESC** | Beendet das Programm. |
|
||||
|
||||
## 📂 Projektstruktur
|
||||
|
||||
```text
|
||||
imx500_gui/
|
||||
├─ app.py # Haupt-Controller, Event-Loop, Layout, verbindet alle Komponenten
|
||||
├─ detector.py # IMX500Detector, Det, FrameSnapshot (Hardware + Parsing)
|
||||
├─ steps.py # StepTransformer + STEP_TEXT (fachliche Schritte)
|
||||
├─ ui/
|
||||
│ ├─ __init__.py
|
||||
│ ├─ theme.py # Theme (Farben, Radii, Styles)
|
||||
│ ├─ textlayout.py # TextLayout (Wrap, Font-Fitting)
|
||||
│ └─ renderer.py # Renderer (alle Zeichenoperationen)
|
||||
|
||||
Zentrale Design-Idee:
|
||||
Jede Datei/Klasse hat genau eine Hauptverantwortung (Single Responsibility Principle). [web:410] Der Code lässt sich so leicht lesen, testen und in Unterricht/Präsentationen verwenden.
|
||||
Installation & Voraussetzungen
|
||||
|
||||
Raspberry Pi mit IMX500-Kamera.
|
||||
|
||||
Python 3.10+.
|
||||
|
||||
Bibliotheken:
|
||||
|
||||
Picamera2 (inkl. IMX500-Unterstützung). [web:397][web:403]
|
||||
|
||||
Pygame (für GUI und Event-Handling). [web:392][web:405]
|
||||
|
||||
Beispiel (vereinfachte Installation, kann je nach System abweichen):
|
||||
|
||||
bash
|
||||
sudo apt update
|
||||
sudo apt install python3-picamera2 python3-pygame
|
||||
# IMX500-spezifische Pakete laut Hersteller/Distribution installieren
|
||||
|
||||
Ausführen
|
||||
|
||||
Im Projektverzeichnis (wo imx500_gui/ liegt):
|
||||
|
||||
bash
|
||||
python3 -m imx500_gui.app \
|
||||
--model=/usr/share/imx500-models/imx500_network_ssd_mobilenetv2_fpnlite_320x320_pp.rpk
|
||||
|
||||
Wichtige Optionen:
|
||||
|
||||
--model: Pfad zum IMX500-Modell (.rpk).
|
||||
|
||||
--threshold: Konfidenzschwelle für Detections (Standard: 0.55).
|
||||
|
||||
--iou: IOU-Schwelle für NMS (Standard: 0.65).
|
||||
|
||||
--max-detections: Maximale Anzahl an Boxen.
|
||||
|
||||
--cam-width, --cam-height: Auflösung des Kamera-Streams.
|
||||
|
||||
Beispiel:
|
||||
|
||||
bash
|
||||
python3 -m imx500_gui.app \
|
||||
--model=/usr/share/imx500-models/imx500_network_ssd_mobilenetv2_fpnlite_320x320_pp.rpk \
|
||||
--threshold=0.55 --iou=0.65 --max-detections=10
|
||||
|
||||
Bedienung der GUI
|
||||
|
||||
SPACE
|
||||
|
||||
In LIVE: friert ein Frame ein und wechselt nach ANALYSE, Step 1.
|
||||
|
||||
In ANALYSE: beendet die Analyse und kehrt zu LIVE zurück.
|
||||
|
||||
ENTER
|
||||
|
||||
In ANALYSE: zum nächsten Schritt (max. Step 4).
|
||||
|
||||
BACKSPACE
|
||||
|
||||
In ANALYSE: zum vorherigen Schritt (min. Step 1).
|
||||
|
||||
ESC oder q
|
||||
|
||||
Anwendung beenden.
|
||||
|
||||
Im LIVE-Modus läuft kontinuierlich die Kamera, Detections werden über dem Videobild als Boxen angezeigt, während im ANALYSE-Modus ein Snapshot in den vier didaktischen Schritten visualisiert wird.
|
||||
Architektur & Klassen
|
||||
detector.py
|
||||
|
||||
Klassen: Det, FrameSnapshot, IMX500Detector
|
||||
|
||||
Det
|
||||
Reine Datenklasse für ein einzelnes Objekt (label, conf, box).
|
||||
|
||||
FrameSnapshot
|
||||
Kapselt einen eingefrorenen Frame inklusive Metadaten:
|
||||
|
||||
frame_rgb: letzter RGB‑Frame.
|
||||
|
||||
src_size: Originalgröße des Frames (Breite, Höhe).
|
||||
|
||||
dets: Liste aller Detections.
|
||||
|
||||
top_dets: Top‑3 Detections (für Box-Overlay).
|
||||
|
||||
top3: Top‑3 Labels + Scores (für Score-Panel).
|
||||
|
||||
IMX500Detector
|
||||
|
||||
Konfiguration des IMX500 (Netzwerk, Labels, Postprocessing). [web:397]
|
||||
|
||||
Initialisierung und Betrieb von Picamera2 (Preview-Stream).
|
||||
|
||||
capture_snapshot(): Ein Frame + Detections → FrameSnapshot.
|
||||
|
||||
parse_detections(): Postprocessing der Netzwerkoutputs (inkl. NMS, Koordinaten-Konvertierung).
|
||||
|
||||
steps.py
|
||||
|
||||
Klassen/Strukturen: StepInfo, STEP_TEXT, StepTransformer
|
||||
|
||||
StepInfo
|
||||
Titel + Body-Text eines Schritts (für das rechte Panel).
|
||||
|
||||
STEP_TEXT
|
||||
Mapping von Schrittindex (1–4) auf StepInfo, beschreibt in natürlicher Sprache:
|
||||
|
||||
Vorverarbeitung.
|
||||
|
||||
Merkmalsextraktion (Kanten/Konturen).
|
||||
|
||||
Klassifizierung (Scores).
|
||||
|
||||
Lokalisierung (Bounding Boxes).
|
||||
|
||||
StepTransformer
|
||||
|
||||
Implementiert die Bildtransformationen für das linke Video-Panel:
|
||||
|
||||
Step 1: Originalbild (Overlays im Renderer).
|
||||
|
||||
Step 2: Binarisierte, vignettiert verstärkte Grauansicht.
|
||||
|
||||
Step 3: Kanten/Konturen mit Sobel, invertiert.
|
||||
|
||||
Step 4: Originalbild (Overlays im Renderer).
|
||||
|
||||
Die Logik ist vollständig von Pygame entkoppelt und nutzt ausschließlich NumPy-Operationen.
|
||||
ui/theme.py
|
||||
|
||||
Klasse: Theme
|
||||
|
||||
Zentraler Ort für:
|
||||
|
||||
Hintergrundfarbe, Panel-Farben, Linien.
|
||||
|
||||
Text-Farben (normal/muted).
|
||||
|
||||
Akzentfarben (Scores).
|
||||
|
||||
Border-Radius (RADIUS).
|
||||
|
||||
Anpassungen am Look & Feel erfolgen hier, ohne Logikcode zu berühren.
|
||||
|
||||
ui/textlayout.py
|
||||
|
||||
Klasse: TextLayout
|
||||
|
||||
Zuständig für:
|
||||
|
||||
wrap_lines(...): Wortweise Zeilenumbrüche basierend auf font.size() und Panelbreite. [web:254]
|
||||
|
||||
fit_title_and_body(...): Binäre Suche auf Fontgröße, bis Titel und Body in die vorgesehene Fläche passen.
|
||||
|
||||
draw_wrapped_lines(...): Zeichnet umbrochene Texte auf eine Oberfläche (inkl. Zeilenabstand).
|
||||
|
||||
Die Klasse ist bewusst generisch gehalten, so dass sie auch in anderen Pygame-Projekten wiederverwendbar ist. [web:411][web:416]
|
||||
ui/renderer.py
|
||||
|
||||
Klasse: Renderer
|
||||
|
||||
Rendering-Layer für alles, was gezeichnet wird:
|
||||
|
||||
Karten/Panels (abgerundete Rechtecke, Outlines).
|
||||
|
||||
Text-Rendering (Labels, Überschriften).
|
||||
|
||||
Pills (Boxen hinter Labels).
|
||||
|
||||
Pixel-Grid (für Step 1 „RGB Pixel“).
|
||||
|
||||
Step-Indikator (4 Kreise + Fortschrittslinie).
|
||||
|
||||
Score-Balkendiagramm (inkl. Threshold-Linie). [web:405]
|
||||
|
||||
Wichtige Methoden:
|
||||
|
||||
draw_card(...), draw_text(...)
|
||||
|
||||
draw_pixel_grid(...), draw_pill(...)
|
||||
|
||||
rect_in_video_coords(...): rechnet Boxen von Quellgröße auf Video-Panel um.
|
||||
|
||||
draw_step_indicator(...)
|
||||
|
||||
draw_bar_chart(...)
|
||||
|
||||
app.py
|
||||
|
||||
Klasse: App
|
||||
|
||||
Orchestriert alle Komponenten:
|
||||
|
||||
Instanziiert IMX500Detector, StepTransformer, TextLayout, Renderer, Theme.
|
||||
|
||||
Verwaltet den Zustand:
|
||||
|
||||
mode: "LIVE" oder "ANALYSE".
|
||||
|
||||
step: 0–4.
|
||||
|
||||
snapshot: aktueller FrameSnapshot.
|
||||
|
||||
Implementiert den Event-Loop (Pygame):
|
||||
|
||||
handle_events(): Tastatur-Eingaben verarbeiten. [web:392][web:396]
|
||||
|
||||
update(): im LIVE-Modus Snapshot aktualisieren.
|
||||
|
||||
draw(): Layout berechnen und Rendering in drei klar getrennte Bereiche aufteilen:
|
||||
|
||||
_draw_left_view(...)
|
||||
|
||||
_draw_header(...)
|
||||
|
||||
_draw_right_panel(...)
|
||||
|
||||
Ablauf:
|
||||
|
||||
LIVE: kontinuierliches Capturing über IMX500Detector.
|
||||
|
||||
SPACE: Snapshot einfrieren, in ANALYSE wechseln (Step 1).
|
||||
|
||||
ENTER / BACKSPACE: Steps 1–4 durchlaufen (verschiedene Visualisierungen).
|
||||
|
||||
SPACE: zurück zu LIVE.
|
||||
|
||||
UML-Diagramm (Textform)
|
||||
|
||||
Für den Projektbericht oder die Dokumentation kann folgende UML-Klassenübersicht genutzt werden (vereinfachte Darstellung):
|
||||
|
||||
text
|
||||
+----------------------+
|
||||
| IMX500Detector |
|
||||
+----------------------+
|
||||
| - args |
|
||||
| - imx500 |
|
||||
| - intrinsics |
|
||||
| - picam2 |
|
||||
+----------------------+
|
||||
| + capture_snapshot() |
|
||||
| + parse_detections() |
|
||||
| + stop() |
|
||||
+----------------------+
|
||||
|
||||
+----------------------+
|
||||
| Det |
|
||||
+----------------------+
|
||||
| + label: str |
|
||||
| + conf: float |
|
||||
| + box: (x,y,w,h) |
|
||||
+----------------------+
|
||||
|
||||
+------------------------------+
|
||||
| FrameSnapshot |
|
||||
+------------------------------+
|
||||
| + frame_rgb: np.ndarray? |
|
||||
| + src_size: (int,int) |
|
||||
| + dets: List[Det] |
|
||||
| + top3: List[(str,float)] |
|
||||
| + top_dets: List[Det] |
|
||||
+------------------------------+
|
||||
|
||||
+----------------------+
|
||||
| StepTransformer |
|
||||
+----------------------+
|
||||
| + apply(frame,step) |
|
||||
+----------------------+
|
||||
|
||||
+----------------------+
|
||||
| StepInfo |
|
||||
+----------------------+
|
||||
| + title: str |
|
||||
| + body: str |
|
||||
+----------------------+
|
||||
|
||||
+----------------------+
|
||||
| Theme |
|
||||
+----------------------+
|
||||
| + BG |
|
||||
| + PANEL |
|
||||
| + ... |
|
||||
+----------------------+
|
||||
|
||||
+---------------------------+
|
||||
| TextLayout |
|
||||
+---------------------------+
|
||||
| + wrap_lines(...) |
|
||||
| + draw_wrapped_lines(...) |
|
||||
| + fit_title_and_body(...) |
|
||||
+---------------------------+
|
||||
|
||||
+----------------------+
|
||||
| Renderer |
|
||||
+----------------------+
|
||||
| - t: Theme |
|
||||
+----------------------+
|
||||
| + draw_card(...) |
|
||||
| + draw_text(...) |
|
||||
| + draw_pixel_grid() |
|
||||
| + draw_pill(...) |
|
||||
| + rect_in_video_... |
|
||||
| + draw_step_... |
|
||||
| + draw_bar_chart() |
|
||||
+----------------------+
|
||||
|
||||
+------------------------------+
|
||||
| App |
|
||||
+------------------------------+
|
||||
| - args |
|
||||
| - theme: Theme |
|
||||
| - detector: IMX500Detector |
|
||||
| - transformer: StepTransformer|
|
||||
| - text_layout: TextLayout |
|
||||
| - renderer: Renderer |
|
||||
| - mode: str |
|
||||
| - step: int |
|
||||
| - snapshot: FrameSnapshot |
|
||||
| - ... |
|
||||
+------------------------------+
|
||||
| + run() |
|
||||
| - handle_events() |
|
||||
| - update() |
|
||||
| - draw() |
|
||||
| - _draw_left_view(...) |
|
||||
| - _draw_header(...) |
|
||||
| - _draw_right_panel(...) |
|
||||
+------------------------------+
|
||||
|
||||
Beziehungen:
|
||||
- App → IMX500Detector (Komposition)
|
||||
- App → StepTransformer
|
||||
- App → TextLayout
|
||||
- App → Renderer
|
||||
- App verwendet FrameSnapshot und Det als Datenmodelle
|
||||
- Renderer verwendet Theme
|
||||
- StepTransformer nutzt STEP_TEXT indirekt über App (für Beschreibung) und NumPy für Transformationen
|
||||
|
||||
Dieses Diagramm kannst du entweder direkt übernehmen oder in ein Grafiktool (PlantUML, draw.io, etc.) übertragen und dort als Grafik ausgeben.
|
||||
Design-Entscheidungen (Clean Code / OOP)
|
||||
|
||||
Single Responsibility: Jede Klasse hat genau eine Hauptaufgabe (Detector vs. Schritte vs. Rendering vs. Layout). [web:410]
|
||||
|
||||
Abstraktionsebenen trennen:
|
||||
|
||||
Hardware-Zugriff in detector.py.
|
||||
|
||||
Fachliche Verarbeitung der Schritte in steps.py.
|
||||
|
||||
UI-spezifische Darstellung in ui/.
|
||||
|
||||
Steuerlogik in app.py. [web:417]
|
||||
|
||||
Lesbare Struktur:
|
||||
Der Hauptloop in App.run() ist kurz, komplexere Aufgaben sind in kleine, gut benannte Methoden ausgelagert. [web:396][web:405]
|
||||
|
||||
Wiederverwendbarkeit:
|
||||
TextLayout und Renderer sind ausreichend generisch, um in anderen Pygame-Projekten genutzt zu werden. [web:411][web:416]
|
||||
|
||||
Mögliche Erweiterungen
|
||||
|
||||
Demo-Mode ohne Hardware:
|
||||
|
||||
DummyDetector implementieren, der statt der Kamera ein Beispielbild lädt.
|
||||
|
||||
Ideal für Präsentationen oder Entwicklung auf einem Laptop ohne IMX500.
|
||||
|
||||
Konfigurationsdatei:
|
||||
|
||||
Thresholds, Farben, Texte aus einer .toml/.yaml laden, um Code-Anpassungen zu minimieren.
|
||||
|
||||
Testbarkeit:
|
||||
|
||||
Unit-Tests für StepTransformer (Form, Wertebereiche).
|
||||
|
||||
Tests für TextLayout-Funktionen (Zeilenumbrüche, Fontgrößen).
|
||||
|
||||
Logging:
|
||||
|
||||
FPS, Anzahl Detections, aktuelle Step-Nummer per Logging-Modul ausgeben.
|
||||
|
||||
Lizenz und Autorenschaft
|
||||
|
||||
Lizenz (z.B. MIT/Apache‑2.0) in einer separaten LICENSE-Datei definieren.
|
||||
|
||||
In README.md und am Kopf der Python-Dateien können Autor:in, Datum, Projektkontext und Versionsstand dokumentiert werden.
|
||||
├── app.py # Hauptprogramm (Controller, Event-Loop)\
|
||||
├── detector.py # Hardware-Interface (Kamera, IMX500 Post-Processing)\
|
||||
├── steps.py # Texte und Bild-Transformationen (Logik)\
|
||||
├── README.md # Dokumentation\
|
||||
├── ui/ # UI-Modul (View)\
|
||||
│ ├── __init__.py\
|
||||
│ ├── renderer.py # Zeichenfunktionen (Balken, Overlay, Pixel-Grid)\
|
||||
│ ├── textlayout.py # Textumbruch und -formatierung\
|
||||
│ └── theme.py # Farben und Design-Konstanten\
|
||||
└── assets/ # Medien-Dateien\
|
||||
├── Kanit-Bold.ttf # Schriftart\
|
||||
├── landingpagebg.jpg # Hintergrundbild\
|
||||
├── audio/ # MP3 Sprachdateien (DE & EN)\
|
||||
├── schritt_1_experte/ # Bildsequenz Animation Schritt 1\
|
||||
├── schritt_2_experte/ # Bildsequenz Animation Schritt 2\
|
||||
├── ... # (weitere Ordner bis schritt_7)\
|
||||
└── schritt_7_experte/\
|
||||
```
|
||||
|
||||
## 🌍 Sprache & Audio
|
||||
|
||||
1. Sprachwechsel: Klicke oben rechts auf den Button DE / EN, um die Sprache der Texte und des Audios zu wechseln.
|
||||
|
||||
2. Audio-Dateien:
|
||||
|
||||
* Deutsch: schueler_step_X.mp3
|
||||
|
||||
* Englisch: schueler_step_X_english.mp3
|
||||
|
||||
* Die Dateien müssen im Ordner assets/audio/ liegen.
|
||||
|
||||
## 📝 Lizenz
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
|
||||
|
|
|
|||
Loading…
Reference in a new issue