Raspberry Pi Raw 10-Bit-Bild als 16-Bit-PNG mit pypng speichern

English Deutsch

In unserem vorherigen Beitrag How to capture RaspberryPi camera 10-bit raw image in Python haben wir gezeigt, wie du die picamera-Python-Bibliothek verwenden kannst, um rohe 10-Bit-Bilddaten zu erfassen.

Das PNG-Bildformat unterstützt das Speichern von 16-Bit-Bilddaten. Dieser Beitrag zeigt dir, wie du das mit den NumPy-Arrays machst, die wir in unserem vorherigen Beitrag erzeugt haben. Wir verwenden die pypng-Bibliothek.

save_10bit_to_16bit_png.py
with open('16bit.png', 'wb') as outfile:
    writer = png.Writer(width=rawimg.shape[1], height=rawimg.shape[0], bitdepth=16, greyscale=False)
    # rawimg ist ein (w, h, 3) RGB uint16-Array
    # aber PyPNG benötigt ein (w, h*3) Array
    png_data = np.reshape(rawimg, (-1, rawimg.shape[1]*3))
    # 10-Bit-Daten auf 16-Bit-Werte skalieren (sonst erscheint es schwarz)
    # HINWEIS: Je nach Foto und Einstellungen
    #  kann es immer noch recht dunkel erscheinen!
    png_data *= int(2**6)
    writer.write(outfile, png_data)

Beachte, dass die resultierenden PNGs ca. 9,9 Megabyte groß sind und das Speichern mit pypng auf meinem Raspberry Pi 3 etwa 27 Sekunden dauert!

Zum Vergleich: Die rohen NumPy-Daten sind ca. 29 Megabyte, während die komprimierten NumPy-Daten 9,3 Megabyte sind.

Wenn deine Motivation für die Verwendung von PNG also Platzersparnis ist, bist du möglicherweise besser mit komprimierten NumPy-Daten bedient, besonders wenn du viele Kamera-Frames in schneller Folge speichern musst und daher limitiert bist.

Falls du PNGs verwenden musst, könntest du Pypy ausprobieren, da pypng eine reine Python-Bibliothek ist und daher von Pypys erhöhter Ausführungsgeschwindigkeit profitieren könnte. In der Praxis ist pypy3 jedoch mehr als 10x langsamer. Bitte lies unsere detaillierte Analyse unter Is pypng 16-bit PNG encoding faster using pypy on the Raspberry Pi?

Vollständiges Beispiel:

save_10bit_full_example.py
#!/usr/bin/env python3
import picamera
import picamera.array
import numpy as np
import png

# Bild erfassen
print("Capturing image...")
with picamera.PiCamera() as camera:
    with picamera.array.PiBayerArray(camera) as stream:
        camera.capture(stream, 'jpeg', bayer=True)
        # Daten demosaicing und in rawimg schreiben
        # (stream.array enthält die nicht-demosaiced-Daten)
        rawimg = stream.demosaic()

# In PNG schreiben
print("Writing 16-bit PNG...")
with open('16bit.png', 'wb') as outfile:
    writer = png.Writer(width=rawimg.shape[1], height=rawimg.shape[0], bitdepth=16, greyscale=False)
    # rawimg ist ein (w, h, 3) RGB uint16-Array
    # aber PyPNG benötigt ein (w, h*3) Array
    png_data = np.reshape(rawimg, (-1, rawimg.shape[1]*3))
    # 10-Bit-Daten auf 16-Bit-Werte skalieren (sonst erscheint es schwarz)
    # HINWEIS: Je nach Foto und Einstellungen
    #  kann es immer noch recht dunkel erscheinen!
    png_data *= int(2**6)
    writer.write(outfile, png_data)

Check out similar posts by category: Raspberry Pi