Как подключить живые видеокадры от ffmpeg до PIL?

Мне нужно использовать ffmpeg / avconv для передачи jpg-кадров в объект PIL PIL ( Pillow ) Image, используя gst в качестве посредника *. Я везде искал этот ответ без большой удачи. Я думаю, что я рядом, но я застрял. Использование Python 2.7

Мой идеальный конвейер, запущенный из python, выглядит так:

  1. ffmpeg / avconv (как видео h264)
  2. Трубопроводы ->
  3. gst-streamer (рамы разделены на jpg)
  4. Трубопроводы ->
  5. Объект Pil Image

У меня есть первые несколько шагов под контролем как одна команда, которая пишет .jpg на диск так же быстро, как это позволит оборудование.

Эта команда выглядит примерно так:

command = [ "ffmpeg", "-f video4linux2", "-r 30", "-video_size 1280x720", "-pixel_format 'uyvy422'", "-i /dev/video0", "-vf fps=30", "-f H264", "-vcodec libx264", "-preset ultrafast", "pipe:1 -", "|", # Pipe to GST "gst-launch-1.0 fdsrc !", "video/x-h264,framerate=30/1,stream-format=byte-stream !", "decodebin ! videorate ! video/x-raw,framerate=30/1 !", "videoconvert !", "jpegenc quality=55 !", "multifilesink location=" + Utils.live_sync_path + "live_%04d.jpg" ] 

Это будет успешно записывать фреймы на диск, если они запускаются с помощью popen или os.system.

Но вместо того, чтобы записывать кадры на диск, я хочу захватить вывод в моем субпроцессном канале и читать кадры, как они написаны, в файловом буфере, который затем может быть прочитан PIL.

Что-то вроде этого:

  import subprocess as sp import shlex import StringIO clean_cmd = shlex.split(" ".join(command)) pipe = sp.Popen(clean_cmd, stdout = sp.PIPE, bufsize=10**8) while pipe: raw = pipe.stdout.read() buff = StringIO.StringIO() buff.write(raw) buff.seek(0) # Open or do something clever... im = Image.open(buff) im.show() pipe.flush() 

Этот код не работает – я даже не уверен, что могу использовать «while pipe» таким образом. Я довольно новичок в использовании буферов и трубопроводов таким образом.

Я не уверен, как бы я знал, что изображение было записано в трубу или когда было прочитано «следующее» изображение.

Любая помощь была бы очень признательна в понимании того, как читать изображения с канала, а не на диск.

  • Это, в конечном счете, трубопровод малины Pi 3, и для увеличения частоты кадров я не могу (A) читать / записывать на диск или с диска (B) использовать метод кадровой захвата – в отличие от запуска видео H246 непосредственно из чип камеры.

One Solution collect form web for “Как подключить живые видеокадры от ffmpeg до PIL?”

Я предполагаю, что конечная цель состоит в том, чтобы обрабатывать USB-камеру с высокой частотой кадров в Linux, и следующий вопрос касается этого вопроса.

Во-первых, хотя несколько USB-камер поддерживают H.264, драйвер Linux для USB-камер (драйвер UVC) в настоящее время не поддерживает поточную полезную нагрузку, которая включает H.264, см. Таблицу «UVC Feature» на домашней странице драйвера . Инструменты пользовательского пространства, такие как ffmpeg, используют драйвер, поэтому имеют те же ограничения, что и формат видео для передачи USB.

Хорошей новостью является то, что если камера поддерживает H.264, она почти наверняка поддерживает MJPEG, который поддерживается драйвером UVC и достаточно хорошо сжимается для поддержки 1280×720 с частотой 30 кадров в секунду по USB 2.0. Вы можете перечислить видеоформаты, поддерживаемые вашей камерой, с помощью v4l2-ctl -d 0 --list-formats-ext . Для Microsoft Lifecam Cinema, например, 1280×720 поддерживается только с частотой 10 кадров в секунду для YUV 4: 2: 2, но при 30 fps для MJPEG.

Для чтения с камеры у меня есть хороший опыт работы с OpenCV. В одном из моих проектов у меня есть 24 (!) Lifecams, подключенных к одной 6-ядерной машине i7 Ubuntu, которая осуществляет отслеживание плодовых мух в режиме реального времени с использованием 320×240 при 7,5 кадрах в секунду на камеру (а также сохраняет MJPEG AVI для каждой камеры иметь запись об эксперименте). Поскольку OpenCV напрямую использует API V4L2, он должен быть быстрее, чем решение, использующее ffmpeg, gst-streamer и два канала.

Код Bare bones (без ошибок) для чтения с камеры с использованием OpenCV и создания изображений PIL выглядит следующим образом:

 import cv2 from PIL import Image cap = cv2.VideoCapture(0) # /dev/video0 while True: ret, frame = cap.read() if not ret: break pil_img = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) ... # do something with PIL image 

Заключительное примечание: вам, вероятно, нужно построить версию OpenCV версии v4l для получения сжатия (MJPEG), см. Этот ответ .

  • Подключение MySQL к Python 3.6
  • Как заставить сервопривод медленно достичь желаемого угла?
  • Python на вкладке пользователя Raspberry Pi внутри бесконечного цикла пропускает входы при ударе со многими
  • ValueError: отправленный канал недействителен на сервере Raspberry Pi - Controlling GPIO Pin 2 (BOARD) с использованием ошибки Python
  • Python и gpio малина
  • Сканирование QR-кода через zbar и Raspicam modul
  • Установка SDK Informix Client на малиновый pi
  • Как читать данные из Arduino с помощью малины pi через I2C
  • Python - лучший язык программирования в мире.