Зробіть зображення за короткий час, використовуючи модуль камери Raspberry Pi


13

Я працюю над проектом, в якому мені потрібно робити приблизно 30 зображень в секунду (без фільму), використовуючи модуль камери Raspberry Pi.

Я використовую для цього бібліотеку Picamera ( http://picamera.readthedocs.org/en/latest/api.html ), але проблема полягає в тому, що для фотографування потрібно приблизно 0,2 - 0,4 секунди, що довгий шлях. Я вже встановив use_video_portмайно True, яке трохи допомогло, але час ще довгий.

Хтось із вас знає, як робити фотографії за короткий час (приблизно 0,025 секунди) за допомогою Python та модуля камери Raspberry Pi?

Відповіді:


18

Щоб робити фотографії за допомогою пікамери в 0,025 секунди, вам знадобиться частота кадрів, що перевищує 80 кадрів в секунду. Причина вимагати 80 швидкісних кадрів в секунду (враховуючи, що 1 / 0,025 = 40) полягає в тому, що в даний час існує певна проблема, через яку кожен інший кадр може пропускатися в кодер з декількома зображеннями, тому ефективна швидкість зйомки виявляється як половина рамки камери.

Модуль камери Pi здатний до 80 кадрів в секунду на більш пізніх прошивках (див. Режими камери в документах Picamera), але лише при роздільній здатності VGA (запити на більш високу роздільну здатність з частотою кадрів> 30 кадрів в секунду призведе до збільшення масштабу від VGA до потрібної роздільної здатності, тому це обмеження, перед яким ви стикаєтесь навіть зі швидкістю 40 кадрів в секунду). Інша проблема, з якою ви, швидше за все, зіткнетеся, - обмеження швидкості 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 є невеликим (особливо порівняно з VideoCore GPU). Незважаючи на те, що ви можете зробити знімок зі швидкістю 40 кадрів в секунду, ви не зможете виконати будь-яку серйозну обробку цих кадрів зі швидкістю 40 кадрів в секунду навіть з усіма вищезазначеними трюками. Єдиний реалістичний спосіб виконати обробку кадру з такою швидкістю - перевезти кадри по мережі на більш швидку машину або виконати обробку на GPU.


Дякуємо за швидку відповідь! Але у вашій програмі я не зможу обробляти окремі фотографії під час запуску .capture_sequence, правда? Чи є спосіб це зробити? Тому що мені потрібно попрацювати з кожною окремою картиною до наступної лексеми.
Тімо Денк

1
Відповідь змінив, щоб включити метод виконання обробки між кадрами з функцією генератора.
Дейв Джонс

Здається, що .capture_sequence ігнорує клавіатурні порушення. Чи знаєте ви, як обійти це?
Серін

@ Cerin, яким би було споживання електроенергії на щось подібне?
Тед Тейлор життя

Fps для цього рішення швидко, але як зберегти зображення у файлах із потоку?
bakalolo

4

Відповідно до цієї відповіді StackOverflow, ви можете використовувати gstreamer та наступну команду для виконання того, що ви хочете:

raspivid -n -t 1000000 -vf -b 2000000 -fps 25 -o - | gst-launch-1.0 fdsrc ! video/x-h264,framerate=25/1,stream-format=byte-stream ! decodebin ! videorate ! video/x-raw,framerate=10/1 ! videoconvert ! jpegenc ! multifilesink location=img_%04d.jpg

Ця команда, як видається, знімає відеовипуск raspivid для генерації відеопотоку з 25 кадрами в секунду, а потім використовує gstreamer для перетворення відео в окремі зображення jpeg.

У цій статті наведено інструкції щодо встановлення gstreamer1.0 з альтернативного сховища.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.