Um mit Picamera Bilder in 0,025 s aufzunehmen, benötigen Sie eine Bildrate von mindestens 80 fps. Der Grund für die Anforderung von 80 statt 40 Bildern pro Sekunde (vorausgesetzt, 1 / 0.025 = 40) liegt darin, dass derzeit ein Problem vorliegt, bei dem jedes zweite Bild im Mehrbild-Encoder übersprungen wird, sodass sich die effektive Aufnahmerate auf die Hälfte der Bildrate der Kamera beläuft.
Das Pi-Kameramodul unterstützt in späteren Firmwares 80 Bilder pro Sekunde (siehe Kameramodi in den Picamera-Dokumenten), jedoch nur bei einer VGA-Auflösung (Anforderungen für höhere Auflösungen mit Bildraten> 30 Bilder pro Sekunde führen zu einer Hochskalierung von VGA auf die angeforderte Auflösung eine Einschränkung, der Sie sich auch bei 40 fps gegenübersehen würden). Das andere Problem, auf das Sie wahrscheinlich stoßen werden, sind Geschwindigkeitsbegrenzungen für SD-Karten. Mit anderen Worten, Sie müssen wahrscheinlich etwas Schnelleres wie einen Netzwerkanschluss oder In-Memory-Streams erfassen (vorausgesetzt, alle zu erfassenden Bilder passen in den Arbeitsspeicher).
Mit dem folgenden Skript erhalte ich eine Aufnahmerate von ~ 38 fps (dh knapp über 0,025 s pro Bild) auf einem Pi mit einer Übertaktung von 900 MHz:
import io
import time
import picamera
with picamera.PiCamera() as camera:
# Set the camera's resolution to VGA @40fps and give it a couple
# of seconds to measure exposure etc.
camera.resolution = (640, 480)
camera.framerate = 80
time.sleep(2)
# Set up 40 in-memory streams
outputs = [io.BytesIO() for i in range(40)]
start = time.time()
camera.capture_sequence(outputs, 'jpeg', use_video_port=True)
finish = time.time()
# How fast were we?
print('Captured 40 images at %.2ffps' % (40 / (finish - start)))
Wenn Sie zwischen den einzelnen Frames etwas tun möchten, ist dies auch möglich, capture_sequence
indem Sie anstelle einer Liste von Ausgängen eine Generatorfunktion bereitstellen:
import io
import time
import picamera
#from PIL import Image
def outputs():
stream = io.BytesIO()
for i in range(40):
# This returns the stream for the camera to capture to
yield stream
# Once the capture is complete, the loop continues here
# (read up on generator functions in Python to understand
# the yield statement). Here you could do some processing
# on the image...
#stream.seek(0)
#img = Image.open(stream)
# Finally, reset the stream for the next capture
stream.seek(0)
stream.truncate()
with picamera.PiCamera() as camera:
camera.resolution = (640, 480)
camera.framerate = 80
time.sleep(2)
start = time.time()
camera.capture_sequence(outputs(), 'jpeg', use_video_port=True)
finish = time.time()
print('Captured 40 images at %.2ffps' % (40 / (finish - start)))
Beachten Sie, dass im obigen Beispiel die Verarbeitung vor der nächsten Erfassung seriell erfolgt (dh, jede Verarbeitung, die Sie vornehmen, verzögert die nächste Erfassung zwangsläufig). Es ist möglich, diese Latenz mit Threading-Tricks zu reduzieren, dies ist jedoch mit einer gewissen Komplexität verbunden.
Möglicherweise möchten Sie auch nicht codierte Captures für die Verarbeitung untersuchen (wodurch der Aufwand für das Codieren und anschließende Decodieren von JPEGs entfällt). Beachten Sie jedoch, dass die CPU des Pi klein ist (insbesondere im Vergleich zur VideoCore-GPU). Während Sie in der Lage sein können Capture bei 40fps, gibt es keinen Weg wirst du in der Lage sein , bei 40fps jeder ernsthaften Verarbeitung dieses Rahmen durchzuführen , auch mit allen Tricks oben erwähnt. Die einzige realistische Möglichkeit, eine Frame-Verarbeitung mit dieser Rate durchzuführen, besteht darin, die Frames über ein Netzwerk an eine schnellere Maschine zu senden oder die Verarbeitung auf der GPU durchzuführen.