Untuk mengambil gambar dalam jarak 0,025 detik dengan kamera digital, Anda memerlukan kecepatan bingkai lebih dari atau sama dengan 80fps. Alasan untuk membutuhkan 80 lebih dari 40fps (mengingat bahwa 1 / 0,025 = 40) adalah bahwa saat ini ada beberapa masalah yang menyebabkan setiap bingkai lainnya dilewati dalam multi-image encoder sehingga tingkat pengambilan gambar yang efektif berakhir sebagai setengah dari framerate kamera.
Modul kamera Pi mampu menghasilkan 80fps di firmware berikutnya (lihat mode kamera dalam dokumentasi kamera), tetapi hanya pada resolusi VGA (permintaan untuk resolusi yang lebih tinggi dengan framerate> 30fps akan menghasilkan peningkatan dari VGA ke resolusi yang diminta, jadi ini adalah batasan yang akan Anda hadapi bahkan pada 40fps). Masalah lain yang mungkin Anda temui adalah keterbatasan kecepatan kartu SD. Dengan kata lain, Anda mungkin perlu menangkap sesuatu yang lebih cepat seperti port jaringan atau aliran dalam memori (dengan asumsi semua gambar yang Anda perlu ambil akan sesuai dengan RAM).
Script berikut memberi saya tingkat penangkapan ~ 38fps (yaitu tepat di atas 0,025s per pic) pada Pi dengan overclocking yang diatur ke 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)))
Jika Anda ingin melakukan sesuatu di antara setiap frame, ini dimungkinkan bahkan dengan capture_sequence
menyediakan fungsi generator alih-alih daftar output:
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)))
Ingatlah bahwa dalam contoh di atas, pemrosesan terjadi secara serial sebelum penangkapan berikutnya (yaitu pemrosesan yang Anda lakukan tentu akan menunda penangkapan berikutnya). Dimungkinkan untuk mengurangi latensi ini dengan trik threading tetapi melakukan itu melibatkan sejumlah kompleksitas.
Anda mungkin juga ingin melihat ke dalam tangkapan yang tidak disandikan untuk diproses (yang menghapus overhead pengkodean dan kemudian mendekode JPEG). Namun, perlu diingat bahwa CPU Pi kecil (terutama dibandingkan dengan GPU VideoCore). Meskipun Anda mungkin dapat menangkap di 40fps, tidak ada cara Anda akan dapat melakukan pemrosesan serius dari frame tersebut di 40fps bahkan dengan semua trik yang disebutkan di atas. Satu-satunya cara realistis untuk melakukan pemrosesan frame pada tingkat itu adalah mengirimkan frame melalui jaringan ke mesin yang lebih cepat, atau melakukan pemrosesan pada GPU.