Чтобы сделать снимки в 0,025 с с помощью Picamera, вам потребуется частота кадров, превышающая или равная 80 кадр / с. Причина, по которой требуется 80, а не 40 кадров в секунду (учитывая, что 1 / 0,025 = 40), заключается в том, что в настоящее время существует некоторая проблема, которая заставляет пропускать каждый второй кадр в кодировщике с несколькими изображениями, поэтому эффективная скорость захвата сводится к половине частоты кадров камеры.
Модуль камеры Pi способен работать со скоростью 80 кадров в секунду в более поздних прошивках (см. Режимы камеры в документации Picamera), но только с разрешением VGA (запросы на более высокие разрешения с частотой кадров> 30 кадров в секунду приведут к повышению масштаба с VGA до требуемого разрешения, поэтому это ограничение, с которым вы столкнетесь даже на 40fps). Другая проблема, с которой вы, вероятно, столкнетесь, - это ограничения скорости SD-карты. Другими словами, вам, вероятно, понадобится записать что-то более быстрое, например, сетевой порт или потоки в памяти (при условии, что все изображения, которые вам нужно захватить, поместятся в ОЗУ).
Следующий скрипт дает мне скорость захвата ~ 38 кадров в секунду (то есть чуть выше 0,025 с на картинку) на Pi с разгоном, установленным на 900 МГц:
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)))
Если вы хотите сделать что-то между каждым кадром, это возможно даже с capture_sequence
помощью функции генератора вместо списка выходных данных:
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)))
Помните, что в приведенном выше примере обработка выполняется последовательно перед следующим захватом (т. Е. Любая обработка, которую вы выполняете, обязательно задержит следующий захват). Можно уменьшить эту задержку с помощью потоковых трюков, но это сопряжено с определенной сложностью.
Возможно, вы также захотите изучить незакодированные захваты для обработки (которые снимают накладные расходы на кодирование, а затем декодируют JPEG). Однако имейте в виду, что процессор Pi маленький (особенно по сравнению с GPU VideoCore). В то время как вы можете быть в состоянии захвата в 40fps, нет никакого способа , вы собираетесь быть в состоянии выполнить любую серьезную обработку этих кадров в 40fps даже со всеми трюками , упомянутых выше. Единственный реалистичный способ выполнить обработку кадров с такой скоростью - это отправить кадры по сети на более быстрый компьютер или выполнить обработку на графическом процессоре.
Согласно этому ответу StackOverflow вы можете использовать gstreamer и следующую команду, чтобы выполнить то, что вы хотите:
Эта команда, по-видимому, принимает видеовыход raspivid для генерации видеопотока со скоростью 25 кадров в секунду, а затем использует gstreamer для преобразования видео в отдельные изображения JPEG.
В этой статье приводятся инструкции по установке gstreamer1.0 из альтернативного репозитория.
источник