Wie ich meinen Makro-Fotografie-Workflow mit Python, LibRaw und focus-stack vollständig automatisiert habe
TL;DR
SD-Karte einstecken, Script starten, fertig. Automatisches Focus-Stacking für Makro-Fotografie mit der OM-1: Das System erkennt Bildserien, konvertiert RAW-Files, stackt sie und gibt perfekt scharfe Makro-Aufnahmen aus. Alles Open Source, läuft auf macOS.
Tech-Stack: Python • LibRaw • focus-stack • exiftool • YAML
Das Problem: Makro-Stacking ist mühsam
Makro-Fotografie hat ein fundamentales Problem: Schärfentiefe. Bei extremen Vergrößerungen liegt nur ein winziger Bereich im Fokus. Die Lösung? Focus-Stacking – mehrere Bilder mit unterschiedlichen Fokusebenen zu einem komplett scharfen Bild kombinieren.
Das manuelle Ritual
- 📸 Fotos machen (10-50 Bilder pro Motiv)
- 💾 SD-Karte in den Rechner
- 📁 Bilder sortieren (welche gehören zusammen?)
- 🔄 RAW-Files konvertieren (ORF → TIFF)
- 🔬 In Stacking-Software laden
- ⏳ Warten…
- 💾 Ergebnis speichern
- 🔁 Für jede Serie wiederholen
Das nervt. Besonders wenn man 5-10 Serien pro Session hat.
Die Vision: Komplette Automation
Was wäre, wenn das alles automatisch passiert?
SD-Karte einstecken
↓
Script starten
↓
☕ Kaffee trinken
↓
Fertige Bilder im Output-Ordner
Genau das habe ich gebaut.
Das Setup
Hardware
- Kamera: OM System OM-1 (funktioniert mit allen ORF-Kameras)
- Computer: Mac (Intel oder Apple Silicon)
- SD-Kartenleser: Beliebig
Software-Stack
| Tool | Zweck | Warum? |
|---|---|---|
| Python 3.x | Orchestrierung | Flexibel, gut dokumentiert |
| LibRaw | RAW-Konvertierung | Unterstützt OM-1 (dcraw ist zu alt!) |
| focus-stack | Stacking-Engine | Open Source, gute Makro-Qualität |
| exiftool | EXIF-Daten | Serien-Erkennung via Timestamp |
| PyYAML | Config-Parsing | Lesbare Konfiguration mit Kommentaren |
Optional:
- GPS-Logger (iPhone) für GPS-Tagging
Architektur: Wie funktioniert’s?
1. SD-Karten-Erkennung
Das Script durchsucht /Volumes/ nach gemounteten Volumes mit DCIM-Ordner:
def find_sd_cards(self):
volumes_path = Path("/Volumes")
sd_cards = []
for volume in volumes_path.iterdir():
dcim_path = volume / "DCIM"
if dcim_path.exists() and dcim_path.is_dir():
orf_count = len(list(dcim_path.rglob("*.ORF")))
sd_cards.append({
'name': volume.name,
'dcim': dcim_path,
'orf_count': orf_count
})
return sd_cards
Code-Sprache: PHP (php)
Drei Modi:
ask– Interaktive Auswahl bei mehreren Kartenfirst– Erste Karte automatisch nehmenmanual– Fester Pfad aus Config
2. Serien-Erkennung via EXIF-Timestamps
Makro-Serien erkennt man daran, dass Bilder zeitlich nah beieinander liegen:
def find_series(self, images):
threshold = timedelta(seconds=self.config['time_threshold'])
for img, timestamp in sorted_images:
if last_time and (timestamp - last_time) > threshold:
# Neue Serie!
series.append(current_series)
current_series = [img]
else:
current_series.append(img)
Code-Sprache: PHP (php)
Beispiel:
- Bilder um 10:15:00, 10:15:02, 10:15:04 → Serie 1
- Bilder um 10:20:00, 10:20:02 → Serie 2 (mehr als 30s Pause)
Warum nicht Dateinamen?
- Kamera resettet Nummern
- Mehrere Sessions durcheinander
- EXIF-Timestamp ist immer korrekt
3. RAW-Konvertierung: Das dcraw-Problem
Problem: Die OM-1 kam 2022 raus. Das klassische dcraw (letztes Update: 2018) kennt das ORF-Format der OM-1 nicht richtig.
Symptom: Unexpected end of file oder Cannot use camera white balance
Lösung: LibRaw – der aktive Fork von dcraw mit Support für neue Kameras.
# OM-1 ORF zu 16-bit TIFF
dcraw_emu -6 -T -w -o 1 -q 3 image.ORF
Code-Sprache: CSS (css)
Wichtig: Das -6 Flag für 16-bit Output!
Bei 8-bit verliert man zu viel Farbtiefe. Das Stacking-Ergebnis wird verrauscht und sieht aus wie ein schlechter Instagram-Filter.
Quirk: dcraw_emu erstellt image.ORF.tiff (nicht image.tiff) – das Script benennt automatisch um.
4. Focus-Stacking mit focus-stack
Warum focus-stack?
| Feature | focus-stack | Helicon Focus | Zerene Stacker |
|---|---|---|---|
| Preis | Kostenlos | ~$200 | ~$300 |
| CLI | ✅ Ja | ⚠️ Eingeschränkt | ⚠️ Eingeschränkt |
| Qualität | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| Automation | ✅ Perfekt | ❌ Schwierig | ❌ Schwierig |
Für Automation ist eine echte CLI essentiell. focus-stack liefert.
Optimale Parameter für Makro:
focus-stack \
--output=result.jpg \
--consistency=3 \ # Alignment-Strenge (2-5)
--denoise=0.5 \ # Leichte Rauschunterdrückung
*.tiff
Code-Sprache: PHP (php)
Parameter-Tuning:
consistency=2→ Schnell, tolerant, mehr Artefakteconsistency=5→ Langsam, streng, weniger Fehlerdenoise=0→ Maximale Schärfe, mehr Rauschendenoise=2→ Starke Glättung, weniger Detail
5. Workflow-Orchestrierung
Das Python-Script koordiniert alle Schritte:
def stack_series(self, images, output_name):
# 1. Bilder kopieren (SD-Karte → /tmp)
copied_images = self.copy_images(images)
# 2. RAW konvertieren (ORF → 16-bit TIFF)
tiff_files = self.convert_raw(copied_images)
# 3. Stacking
self.focus_stack(tiff_files, output_name)
# 4. Cleanup
self.cleanup_temp()
Code-Sprache: PHP (php)
Warum erst kopieren?
dcraw/LibRaw hat Probleme beim direkten Lesen von SD-Karten (USB-Latenz, Dateisystem-Quirks). Lokale Kopie ist stabiler und schneller.
Die Config: YAML statt JSON
Anfangs hatte ich JSON mit _comment_*-Keys. Das war hässlich.
Jetzt: YAML mit echten Kommentaren!
# ═══════════════════════════════════════════
# OM-1 Makro-Stacking Pipeline
# ═══════════════════════════════════════════
# SD-Karten-Modus
# 'ask' = immer fragen
# 'first' = erste nehmen
# 'manual' = fester Pfad
sd_card_mode: ask
# Serien-Erkennung
# Max. Sekunden zwischen Bildern einer Serie
time_threshold: 30
# Mindestanzahl Bilder pro Serie
min_images: 3
# Stacking-Software
stacker: focus-stack
stacker_binary: ~/bin/focus-stack/focus-stack.app/Contents/MacOS/focus-stack
# focus-stack Parameter
consistency: 3 # 2-5, höher = strenger
denoise: 0.5 # 0-2, Rauschunterdrückung
# RAW-Konvertierung
convert_raw: true
raw_converter: libraw
# Output
output_dir: ~/Pictures/Stacked
output_format: jpg
output_quality: 95
Code-Sprache: YAML (yaml)
Viel lesbarer als JSON!
Installation
Schritt 1: Dependencies
# Homebrew (falls noch nicht installiert)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Tools installieren
brew install python3 exiftool libraw
# Python-Dependencies
pip3 install pyyaml
Code-Sprache: PHP (php)
Schritt 2: focus-stack
# Download von GitHub Releases
cd ~/Downloads
# https://github.com/PetteriAimonen/focus-stack/releases
# → focus-stack-macos.zip herunterladen
# Entpacken und installieren
unzip focus-stack-*.zip
mkdir -p ~/bin
mv focus-stack ~/bin/
chmod +x ~/bin/focus-stack
# Testen
~/bin/focus-stack --help
Code-Sprache: PHP (php)
Schritt 3: Script einrichten
# Ordner erstellen
mkdir -p ~/scripts
# Script erstellen
nano ~/scripts/macro_stacking.py
# (Code einfügen – siehe unten)
# Ausführbar machen
chmod +x ~/scripts/macro_stacking.py
Code-Sprache: PHP (php)
Schritt 4: Erste Ausführung
# Erstellt Config-Datei
python3 ~/scripts/macro_stacking.py
# Config anpassen
nano ~/.stacking_config.yaml
Code-Sprache: PHP (php)
Das komplette Script
Das Script ist modular aufgebaut und ca. 250 Zeilen Python:
#!/usr/bin/env python3
"""
Automatischer Makro-Stacking-Workflow für OM-1 auf macOS
"""
import os
import subprocess
import shutil
from pathlib import Path
from datetime import datetime, timedelta
class OM1StackingPipeline:
def __init__(self, config_path="~/.stacking_config.yaml"):
self.config = self.load_config(config_path)
self.output_dir = Path(self.config['output_dir']).expanduser()
self.temp_dir = Path(self.config['temp_dir']).expanduser()
self.stacker_bin = Path(self.config['stacker_binary']).expanduser()
self.output_dir.mkdir(parents=True, exist_ok=True)
self.temp_dir.mkdir(parents=True, exist_ok=True)
def load_config(self, path):
"""Config laden oder Default erstellen"""
config_path = Path(path).expanduser()
if not config_path.exists():
# Default-Config mit Kommentaren erstellen
default_config = """# OM-1 Makro-Stacking Pipeline
sd_card_mode: ask
time_threshold: 30
min_images: 3
stacker: focus-stack
stacker_binary: ~/bin/focus-stack
consistency: 3
denoise: 0.5
convert_raw: true
raw_converter: libraw
output_dir: ~/Pictures/Stacked
output_format: jpg
output_quality: 95
"""
config_path.parent.mkdir(parents=True, exist_ok=True)
with open(config_path, 'w') as f:
f.write(default_config)
import yaml
return yaml.safe_load(default_config)
import yaml
with open(config_path) as f:
return yaml.safe_load(f)
def find_sd_cards(self):
"""SD-Karten mit DCIM-Ordner finden"""
volumes_path = Path("/Volumes")
sd_cards = []
for volume in volumes_path.iterdir():
if not volume.is_dir():
continue
# System-Volumes überspringen
if volume.name in ['Macintosh HD', 'Preboot', 'Recovery', 'VM', 'Data']:
continue
dcim_path = volume / "DCIM"
if dcim_path.exists():
orf_count = len(list(dcim_path.rglob("*.ORF")))
sd_cards.append({
'name': volume.name,
'dcim': dcim_path,
'orf_count': orf_count
})
return sd_cards
def select_sd_card(self, sd_cards):
"""SD-Karte auswählen"""
mode = self.config.get('sd_card_mode', 'ask')
if mode == 'first':
return sd_cards[0]
elif mode == 'ask':
print("\n📸 SD-Karten gefunden:\n")
for i, card in enumerate(sd_cards, 1):
print(f" [{i}] {card['name']} ({card['orf_count']} ORF-Files)")
choice = input("\nWelche SD-Karte? [1]: ").strip() or "1"
return sd_cards[int(choice) - 1]
def find_series(self, images):
"""Bilder in Serien gruppieren via EXIF-Timestamp"""
# EXIF-Daten auslesen
images_with_time = []
for img in images:
timestamp = self.get_exif_data(img)
if timestamp:
images_with_time.append((img, timestamp))
# Nach Zeit sortieren
images_with_time.sort(key=lambda x: x[1])
# Serien erkennen
series = []
current_series = []
last_time = None
threshold = timedelta(seconds=self.config['time_threshold'])
for img, timestamp in images_with_time:
if last_time and (timestamp - last_time) > threshold:
if len(current_series) >= self.config['min_images']:
series.append(current_series)
current_series = [img]
else:
current_series.append(img)
last_time = timestamp
if len(current_series) >= self.config['min_images']:
series.append(current_series)
return series
def convert_raw(self, orf_file, output_dir):
"""ORF zu 16-bit TIFF konvertieren"""
subprocess.run([
'dcraw_emu',
'-6', # 16-bit!
'-T', # TIFF
'-w', # Camera WB
'-o', '1', # sRGB
'-q', '3', # Best quality
orf_file.name
], cwd=str(output_dir), check=True, capture_output=True)
# Umbenennen: image.ORF.tiff → image.tiff
output_raw = output_dir / f"{orf_file.name}.tiff"
output = output_dir / f"{orf_file.stem}.tiff"
output_raw.rename(output)
return output
def stack_series(self, images, output_name):
"""Serie stacken"""
temp_dir = self.temp_dir / output_name
temp_dir.mkdir(parents=True, exist_ok=True)
print(f" 📸 Stacke {len(images)} Bilder...")
# 1. Kopieren
copied = [shutil.copy2(img, temp_dir / img.name) for img in images]
# 2. Konvertieren
print(f" 🔄 Konvertiere RAW...")
converted = []
for i, img in enumerate([Path(p) for p in copied], 1):
print(f" [{i}/{len(copied)}] {img.name}", end=" ")
try:
tiff = self.convert_raw(img, temp_dir)
converted.append(tiff)
print("✓")
except:
print("✗")
# 3. Stacking
print(f" 🔬 Stacking...")
output_file = self.output_dir / f"{output_name}.{self.config['output_format']}"
subprocess.run([
str(self.stacker_bin),
f'--output={output_file}',
f'--consistency={self.config["consistency"]}',
f'--denoise={self.config["denoise"]}',
*[str(img) for img in converted]
], check=True, capture_output=True)
# 4. Cleanup
shutil.rmtree(temp_dir)
return output_file
def run(self):
"""Haupt-Pipeline"""
print("╔═══════════════════════════════════════════╗")
print("║ OM-1 Makro-Stacking Pipeline ║")
print("╚═══════════════════════════════════════════╝")
# SD-Karte finden
print("\n🔍 Suche SD-Karten...")
sd_cards = self.find_sd_cards()
if not sd_cards:
print("❌ Keine SD-Karte gefunden!")
return
selected = self.select_sd_card(sd_cards)
# Bilder finden
images = list(selected['dcim'].rglob("*.ORF"))
print(f"\n✓ Gefunden: {len(images)} Bilder")
# Serien erkennen
series = self.find_series(images)
print(f"✓ Erkannt: {len(series)} Serien\n")
# Stacking
success = 0
for i, imgs in enumerate(series, 1):
timestamp = self.get_exif_data(imgs[0])
series_name = f"series_{timestamp.strftime('%Y%m%d_%H%M%S')}"
print(f"━━━ Serie {i}/{len(series)}: {series_name} ━━━")
try:
output = self.stack_series(imgs, series_name)
print(f" ✓ Fertig: {output.name}\n")
success += 1
except Exception as e:
print(f" ❌ Fehler: {e}\n")
print(f"╔═══════════════════════════════════════════╗")
print(f"║ ✓ {success}/{len(series)} Serien gestackt! ║")
print(f"╚═══════════════════════════════════════════╝")
if __name__ == "__main__":
try:
pipeline = OM1StackingPipeline()
pipeline.run()
except KeyboardInterrupt:
print("\n⚠️ Abgebrochen")
Code-Sprache: Python (python)
Vollständiges Script: Download auf GitHub
Usage
Standard-Workflow
# 1. SD-Karte einstecken
# 2. Terminal öffnen
# 3. Script starten
python3 ~/scripts/macro_stacking.py
Code-Sprache: PHP (php)
Output:
╔═══════════════════════════════════════════╗
║ OM-1 Makro-Stacking Pipeline ║
╚═══════════════════════════════════════════╝
🔍 Suche SD-Karten...
📸 SD-Karten gefunden:
[1] untitled (42 ORF-Files)
Welche SD-Karte? [1]:
✓ Gefunden: 42 Bilder
📊 Analysiere Bilder...
✓ Erkannt: 3 Serien
━━━ Serie 1/3: series_20260314_083628 ━━━
📸 Stacke 16 Bilder...
🔄 Konvertiere RAW...
[1/16] P3141806.ORF ✓
[2/16] P3141807.ORF ✓
...
🔬 Stacking...
✓ Fertig: series_20260314_083628.jpg
━━━ Serie 2/3: series_20260314_091522 ━━━
...
╔═══════════════════════════════════════════╗
║ ✓ 3/3 Serien gestackt! ║
╚═══════════════════════════════════════════╝
Mehrere SD-Karten
Das Script zeigt alle verfügbaren Karten:
📸 SD-Karten gefunden:
[1] untitled (42 ORF-Files)
[2] EOS_DIGITAL (18 ORF-Files)
Welche SD-Karte? [1]: 2
✓ Gewählt: EOS_DIGITAL
Code-Sprache: CSS (css)
Automatischer Modus
Für wiederkehrende Workflows:
# Config: ~/.stacking_config.yaml
sd_card_mode: first # Nimmt automatisch erste Karte
Code-Sprache: PHP (php)
python3 ~/scripts/macro_stacking.py
# Keine Interaktion nötig!
Code-Sprache: PHP (php)
Erweiterte Features
GPS-Tagging
Für Außenaufnahmen (oder Makro im Feld):
1. GPS-Track aufzeichnen:
- iPhone: GPX Tracker, Trails, Gaia GPS
- Android: GPS Logger, OsmAnd
- Track als
.gpxexportieren
2. Config anpassen:
gpx_file: ~/Downloads/track_20260314.gpx
Code-Sprache: JavaScript (javascript)
3. Script läuft:
🌍 Füge GPS-Daten hinzu: track_20260314.gpx
✓ GPS-Daten hinzugefügt
Code-Sprache: CSS (css)
Alle Bilder bekommen GPS-Koordinaten basierend auf Aufnahmezeit.
Funktioniert auch für Nicht-Makro-Fotos!
Debug-Modus
Für Troubleshooting:
debug: true
keep_temp: true
Code-Sprache: JavaScript (javascript)
Behält konvertierte TIFF-Files in /tmp/stacking/ zum Inspizieren.
Nützlich wenn:
- Stacking-Qualität schlecht ist
- Alignment fehlschlägt
- Konvertierung Probleme macht
Parameter-Tuning
Für schwierige Motive:
consistency: 5 # Sehr streng (weniger Fehler)
denoise: 0 # Kein Denoise (maximale Schärfe)
Code-Sprache: PHP (php)
Für schnelles Stacking:
consistency: 2 # Toleranter (schneller)
denoise: 1.5 # Mehr Glättung
Code-Sprache: PHP (php)
Mein Sweet-Spot:
consistency: 3
denoise: 0.5
Code-Sprache: HTTP (http)
Troubleshooting
„Keine SD-Karte gefunden“
Check:
ls /Volumes/
ls /Volumes/*/DCIM/
Mögliche Ursachen:
- SD-Karte nicht gemountet
- Kein DCIM-Ordner
- Permissions-Problem
Fix:
# Config: Manuellen Pfad nutzen
sd_card_mode: manual
watch_dir: /Volumes/MEINE_KARTE/DCIM
Code-Sprache: PHP (php)
„dcraw_emu: command not found“
# LibRaw installieren
brew install libraw
# Checken
which dcraw_emu
dcraw_emu --version
Code-Sprache: PHP (php)
„focus-stack crashed“
Mögliche Ursachen:
- Zu wenig RAM (braucht ~2GB pro Serie bei 20MP)
- Korrupte TIFF-Files
- Bilder zu unterschiedlich (Bewegung, Wind)
Debug:
keep_temp: true
Code-Sprache: JavaScript (javascript)
Dann TIFFs in /tmp/stacking/ manuell mit Vorschau öffnen und prüfen.
Schlechte Stacking-Qualität
Checklist:
- ✅ 16-bit TIFF? (Check mit
file image.tiff) - ✅ Genug Bilder? (min. 5-10 für Makro)
- ✅ Stativ benutzt? (Bewegung killt Alignment)
- ✅ Fokus-Schritte klein genug? (Overlap wichtig!)
- ✅ consistency Parameter anpassen
Häufigster Fehler: 8-bit TIFF statt 16-bit → verrauschtes Ergebnis
„Unexpected end of file“ bei dcraw_emu
Ursache: Bilder werden direkt von SD-Karte gelesen (USB-Latenz).
Fix: Script kopiert Bilder erst nach /tmp – sollte nicht mehr auftreten.
Falls doch:
# Anderes Temp-Verzeichnis
temp_dir: ~/tmp/stacking
Code-Sprache: PHP (php)
Performance
Benchmark (M1 MacBook Pro, 20MP ORF-Files):
| Serie | Bilder | RAW → TIFF | Stacking | Total |
|---|---|---|---|---|
| Klein | 7 | 12s | 8s | 20s |
| Mittel | 16 | 28s | 22s | 50s |
| Groß | 32 | 58s | 65s | 2m 3s |
Bottlenecks:
- RAW-Konvertierung: ~1.5-2s pro Bild
- Stacking: ~1-2s pro Bild (abhängig von Auflösung)
- I/O: SSD vs. HDD macht massiven Unterschied
Optimierungen:
- ✅ SSD für
/tmp/stacking(2x schneller) - ✅ 16GB+ RAM (verhindert Swapping)
- ⏳ TODO: Parallele Verarbeitung (mehrere Serien gleichzeitig)
Lessons Learned
1. dcraw ist tot, lang lebe LibRaw
dcraw (2018) kennt moderne Kameras nicht. LibRaw ist Pflicht für neue Kameras wie die OM-1.
Symptom: Unexpected end of file, Cannot use camera white balance
Lösung: brew install libraw, dcraw_emu nutzen
2. 16-bit ist nicht optional
8-bit TIFF sieht nach Stacking katastrophal aus:
- Verrauscht
- Banding in Farbverläufen
- Verlust von Highlight/Shadow-Detail
16-bit ist bei Makro mit hohem ISO essentiell.
Vergleich:
- 8-bit: 256 Helligkeitsstufen pro Kanal
- 16-bit: 65.536 Helligkeitsstufen pro Kanal
Bei 10+ Bildern macht das einen massiven Unterschied.
3. Serien-Erkennung via EXIF > Dateinamen
Anfangs wollte ich nach Dateinamen gruppieren (P3141806.ORF, P3141807.ORF, …).
Probleme:
- Kamera resettet Nummern
- Mehrere Sessions durcheinander
- Lücken in Sequenzen
EXIF-Timestamp ist immer korrekt und funktioniert über Sessions hinweg.
4. YAML > JSON für Configs
JSON ohne Kommentare ist unleserlich. YAML mit echten Kommentaren ist so viel besser.
Vorher (JSON):
{
"_comment_consistency": "2-5, höher = strenger",
"consistency": 3
}
Code-Sprache: JSON / JSON mit Kommentaren (json)
Nachher (YAML):
# Consistency-Level (2-5, höher = strenger)
consistency: 3
Code-Sprache: PHP (php)
Kein Vergleich.
5. Kopieren vor Konvertieren
dcraw/LibRaw hat Probleme beim direkten Lesen von SD-Karten:
- USB-Latenz
- Dateisystem-Quirks (exFAT)
- Timeouts bei langsamen Karten
Lösung: Bilder erst nach /tmp kopieren (schnell, lokal, zuverlässig).
Mögliche Erweiterungen
TODO-Liste:
- Parallele Verarbeitung (mehrere Serien gleichzeitig)
- Hazel-Integration (automatisch bei SD-Karte einstecken)
- Web-UI (Flask-Dashboard mit Live-Progress)
- Qualitäts-Check (verwackelte Bilder aussortieren via Sharpness-Analyse)
- Cloud-Backup (gestackte Bilder automatisch auf NAS/Cloud)
- Helicon Focus Support (bessere Qualität, aber kommerziell)
- Linux/Windows Support (aktuell nur macOS)
- Batch-Reprocessing (alte Serien mit neuen Parametern neu stacken)
Alternative Ansätze
Warum nicht…
…Lightroom/Photoshop?
- ❌ Nicht automatisierbar
- ❌ Teuer (Abo-Modell: 12€/Monat)
- ❌ Closed Source
- ❌ Erfordert manuelle Interaktion
…Helicon Focus?
- ✅ Beste Qualität
- ❌ Kommerziell (~$200)
- ❌ CLI eingeschränkt
- ❌ Für Hobby-Workflow overkill
…Zerene Stacker?
- ✅ Auch sehr gut
- ❌ Teuer (~$300)
- ❌ Ähnliche CLI-Probleme
- ❌ Keine gute Automation
…shinestacker?
- ✅ Kann RAW direkt
- ✅ Open Source
- ❌ Nur Python-API (keine CLI)
- ❌ Komplizierter zu integrieren
…Alles manuell?
- ✅ Funktioniert
- ❌ Zeitverschwendung
- ❌ Fehleranfällig
- ❌ Nicht reproduzierbar
- ❌ Nervt nach der dritten Serie
Fazit
Mit diesem Setup ist Makro-Stacking endlich schmerzfrei:
✅ Keine manuelle Sortierung mehr
✅ Keine RAW-Konvertierung mehr
✅ Kein Klicken durch GUIs mehr
✅ Reproduzierbar und konsistent
✅ Open Source und kostenlos
Einmal eingerichtet läuft es vollautomatisch.
Der neue Workflow:
- 📸 Fotos machen
- 🚀 Script starten
- ☕ Kaffee trinken
- ✅ Fertig
Genau so sollte es sein.
Download & Links
Code:
- 📦 Komplettes Script auf GitHub (TODO: Repository erstellen)
- 📄 Config-Beispiel (YAML)
- 📖 Ausführliche Dokumentation
Tools:
- 🔧 LibRaw
- 🔬 focus-stack
- 📊 exiftool
- 🐍 PyYAML
Hardware:
Weitere Artikel in dieser Serie
- Paperless-NGX Backup-Konzept: Automatisiert, sicher und zuverlässig
- AI Office: Dokumentenarchiv mit Paperless und KI erweitert
- Domain- und Mail-Umzug: Von 1&1 zu Hetzner
Fragen? Verbesserungen? Bugs?
Hinterlasst Kommentare oder schreibt mir: E-Mail
Happy Stacking! 🔬📸✨


Schreibe einen Kommentar