Pour prendre des photos en 0,025 s avec picamera, vous aurez besoin d'une fréquence d'images supérieure ou égale à 80 ips. La raison pour laquelle il faut 80 à 40 images par seconde (étant donné que 1 / 0,025 = 40) est qu'actuellement, il y a un problème qui fait que toutes les autres images sont ignorées dans l'encodeur multi-images, de sorte que le taux de capture effectif se retrouve à la moitié de la fréquence d'images de l'appareil photo.
Le module de caméra du Pi est capable de 80 images par seconde dans les firmwares ultérieurs (voir les modes de caméra dans les documents picamera), mais uniquement à une résolution VGA (les demandes de résolutions plus élevées avec des cadences de trame > 30 images par seconde entraîneront une mise à l'échelle de VGA vers la résolution demandée, c'est donc une limitation que vous rencontriez même à 40 images par seconde). L'autre problème que vous rencontrerez probablement est la limitation de vitesse de la carte SD. En d'autres termes, vous devrez probablement capturer vers quelque chose de plus rapide comme un port réseau ou des flux en mémoire (en supposant que toutes les images que vous devez capturer tiendront dans la RAM).
Le script suivant me permet d'obtenir un taux de capture de ~ 38 ips (c'est-à-dire juste au-dessus de 0,025 s par image) sur un Pi avec un overclocking réglé à 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)))
Si vous souhaitez faire quelque chose entre chaque trame, cela est possible même capture_sequence
en fournissant une fonction de générateur au lieu d'une liste de sorties:
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)))
Gardez à l'esprit que dans l'exemple ci-dessus, le traitement se produit en série avant la prochaine capture (c'est-à-dire que tout traitement que vous effectuez retardera nécessairement la prochaine capture). Il est possible de réduire cette latence avec des astuces de threading mais cela implique une certaine complexité.
Vous pouvez également examiner les captures non encodées pour le traitement (ce qui supprime la surcharge d'encodage puis de décodage des JPEG). Cependant, gardez à l'esprit que le processeur du Pi est petit (surtout par rapport au GPU VideoCore). Bien que vous puissiez capturer à 40 images par seconde, il est impossible que vous puissiez effectuer un traitement sérieux de ces images à 40 images par seconde, même avec toutes les astuces mentionnées ci-dessus. La seule façon réaliste d'effectuer le traitement des trames à ce rythme est d'expédier les trames sur un réseau vers une machine plus rapide ou d'effectuer le traitement sur le GPU.