Para tomar fotos en 0.025s con picamera, necesitará una velocidad de fotogramas mayor o igual a 80 fps. La razón para requerir 80 en lugar de 40 fps (dado que 1 / 0.025 = 40) es que actualmente hay algún problema que hace que se salte cualquier otro cuadro en el codificador de múltiples imágenes, por lo que la tasa de captura efectiva termina como la mitad de la velocidad de fotogramas de la cámara.
El módulo de cámara de Pi es capaz de 80 fps en firmwares posteriores (vea los modos de cámara en los documentos de picamera), pero solo a una resolución VGA (las solicitudes de resoluciones más altas con velocidades de cuadro> 30 fps resultarán en un aumento de VGA a la resolución solicitada, por lo que esto es una limitación que enfrentarías incluso a 40 fps). El otro problema que probablemente encuentres son las limitaciones de velocidad de la tarjeta SD. En otras palabras, probablemente necesite capturar algo más rápido como un puerto de red o transmisiones en memoria (suponiendo que todas las imágenes que necesita capturar quepan en la RAM).
El siguiente script me da una velocidad de captura de ~ 38 fps (es decir, justo por encima de 0.025s por foto) en un Pi con overclocking establecido en 900Mhz:
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)))
Si desea hacer algo entre cada cuadro, esto es posible incluso capture_sequence
proporcionando una función de generador en lugar de una lista de salidas:
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)))
Tenga en cuenta que en el ejemplo anterior, el procesamiento se produce en serie antes de la siguiente captura (es decir, cualquier procesamiento que realice retrasará necesariamente la próxima captura). Es posible reducir esta latencia con trucos de subprocesos, pero hacerlo implica una cierta cantidad de complejidad.
También es posible que desee buscar capturas no codificadas para el procesamiento (que eliminan la sobrecarga de la codificación y luego la decodificación de archivos JPEG). Sin embargo, tenga en cuenta que la CPU de Pi es pequeña (especialmente en comparación con la GPU VideoCore). Si bien es posible que pueda capturar a 40 fps, no hay forma de que pueda realizar un procesamiento serio de esos cuadros a 40 fps, incluso con todos los trucos mencionados anteriormente. La única forma realista de realizar el procesamiento de cuadros a esa velocidad es enviar los cuadros a través de una red a una máquina más rápida, o realizar el procesamiento en la GPU.