Schauen wir uns zunächst die Kameramodule selbst an. Das v1-Kameramodul kann 2x2- und 4x4-Binning durchführen (siehe Tabelle der Kameramodi ). Ich habe gehört, dass es auch einen 8x8-Binning-Modus gibt, aber die Firmware-Entwickler konnten ihn nicht zum Laufen bringen. Aus diesem Grund kann das v1-Modul in den meisten Modi das volle Sichtfeld (FoV) erreichen.
Im Vergleich dazu kann das v2-Kameramodul leider nur 2x2-Binning durchführen, was erklärt, warum viele seiner Modi einen partiellen FoV aufweisen (ich denke, das v2-Modul kann auch Zeilen überspringen, aber ich glaube nicht, dass dies von der Kamera des Pi verwendet wird Firmware). Dies ist jedoch nicht die ganze Geschichte. Dies ist nur der Anfang der Bildverarbeitungspipeline. Mit anderen Worten, dies ist genau das, was der Sensor selbst an den ISP-Block in der GPU weiterleitet, der den Rest der Verarbeitung einschließlich etwaiger Größenänderungen übernimmt. Die Kamera verfügt zwar über mehrere diskrete Modi (in dieser Tabelle aufgeführt), kann jedoch in jedem Modus effektiv arbeitenAuflösung bis zum angegebenen Maximum. Wenn Sie etwas weiter von diesen Tabellen in der Dokumentation lesen, finden Sie eine Beschreibung der Heuristik, mit der der Sensormodus entsprechend der angeforderten Auflösung und Bildrate ausgewählt wird.
Vorausgesetzt, Sie landen in einem Vollbild-Sensormodus oder erzwingen dessen Verwendung, werden Sie ohnehin von allen Pixeln auf dem Sensor erfasst. Bedenken hinsichtlich der CPU-Auslastung: Machen Sie sich keine Sorgen. Die CPU wird für keinen Teil der Imaging-Pipeline der Kamera verwendet, sie basiert fast ausschließlich auf der GPU (mit Ausnahme des ersten Binning-Schritts, der vom Sensor-ISP ausgeführt wird). Die CPU wird nur dann involviert, wenn sie die endgültige Ausgabe empfängt und etwas damit zu tun hat.
Wenn Sie nach einer minimalen CPU-Auslastung suchen, ist dies ein großes Plus des Kameramoduls im Vergleich zu USB-Webcams, die, da der USB-Bus von der CPU abgefragt wird, eine erhebliche CPU-Zeit benötigen (USB3 verwendet Interrupts anstelle von Abfragen, aber wir sind es Ich spreche hier von Pis, die nur USB2 haben, und außerdem: Die meisten USB-Webcams verwenden zum Zeitpunkt des Schreibens kein USB3.
Auf Ihre spezifischen Anforderungen. Sie wollen:
- um ein 120x90 Bild zu erzeugen
- mit vollem Sichtfeld
- in schwarz und weiß (ich nehme an, dass nur Luma in Ordnung ist)
- zu einem Python-Numpy-Array
- so schnell wie möglich
Leicht genug. Wir werden den Sensormodus 4 verwenden, der das volle Sichtfeld bietet und den Sensor verwendet, um eine anfängliche 2x2-Gruppierung durchzuführen. Wir stellen die Ausgabeauflösung der Kamera auf 120 x 90 ein (dies bedeutet einfach, dass der Größenänderungsblock der GPU die 2x2-Sensordaten im Vollbildmodus auf 120 x 90 verkleinert). Schließlich erfassen wir direkt ein Numpy-Array, machen es jedoch nur groß genug für die Y-Ebene (Luminanz) der Daten. Es wird ein Fehler ausgegeben, da das Array nicht groß genug für alle Daten ist, aber das ist in Ordnung. Wir können das ignorieren und die Y-Daten werden trotzdem ausgeschrieben:
import time
import picamera
import numpy as np
with picamera.PiCamera(
sensor_mode=4,
resolution='120x90',
framerate=40) as camera:
time.sleep(2) # let the camera warm up and set gain/white balance
y_data = np.empty((96, 128), dtype=np.uint8)
try:
camera.capture(y_data, 'yuv')
except IOError:
pass
y_data = y_data[:120, :90]
# y_data now contains the Y-plane only
print(y_data.max())
Dies wird mehr oder weniger direkt aus dem YUV- Rezept (Unencoded Image Capture) kopiert, was auch erklärt, warum wir hier tatsächlich 128x96 aufnehmen (die Kamera arbeitet in 32x16-Blöcken).
Was ist mit einer schnellen kontinuierlichen Erfassung? Ich gehe davon aus, dass Sie daran interessiert sind, nur weil Sie dies so schnell wie möglich wollen (was im Allgemeinen bedeutet, dass Sie auch so viele wie möglich wollen). In diesem Fall ist es am besten, eine benutzerdefinierte Ausgabe mit einer YUV-Aufzeichnung zu verwenden (die einen write () -Aufruf pro Frame empfängt) und dann mit der sehr praktischen frombuffer
Methode von numpy ein numpy-Array über die Vorderseite der erfassten Daten zu legen (Hinweis: Dies ist extrem schnell, da wir das Numpy-Array nicht zuweisen oder die Daten nicht kopieren. Wir sagen nur "Erstellen Sie ein Numpy-Array für diesen vorhandenen Speicherblock "):
import time
import picamera
import numpy as np
class MyOutput(object):
def write(self, buf):
# write will be called once for each frame of output. buf is a bytes
# object containing the frame data in YUV420 format; we can construct a
# numpy array on top of the Y plane of this data quite easily:
y_data = np.frombuffer(
buf, dtype=np.uint8, count=128*96).reshape((96, 128))
# do whatever you want with the frame data here... I'm just going to
# print the maximum pixel brightness:
print(y_data[:90, :120].max())
def flush(self):
# this will be called at the end of the recording; do whatever you want
# here
pass
with picamera.PiCamera(
sensor_mode=4,
resolution='120x90',
framerate=40) as camera:
time.sleep(2) # let the camera warm up and set gain/white balance
output = MyOutput()
camera.start_recording(output, 'yuv')
camera.wait_recording(10) # record 10 seconds worth of data
camera.stop_recording()
Obwohl 40 Bilder pro Sekunde Bilddaten in Numpy-Arrays erzeugt werden, ist die CPU-Auslastung dieses Skripts minimal. Kommentieren Sie die print-Anweisung aus, die eigentlich ziemlich CPU-lastig ist, um die Gesamt-CPU-Auslastung zu sehen: Auf meinem Pi3 sind es ungefähr 2%, sodass für die gewünschte Bildverarbeitung noch viel übrig bleibt.
v4l2-ctl
um Einstellungen an der Kamera vorzunehmen, mit denen Sie das/dev/video
Gerät direkt verwenden können. Ich würde das versuchen und sehen, wie es dir geht. Wenn Sie nicht weiterkommen, wenden Sie sich an den Autor, wenn Sie ein echtes Problem oder eine Frage haben. Er ist ein sehr netter Kerl, der gerne bei echten Problemen hilft. Viel Glück und bitte antworten Sie, wie Sie Ihr Problem gelöst haben.