Проблема с настройкой cv2.VideoWriter и GStreamer.Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Проблема с настройкой cv2.VideoWriter и GStreamer.

Сообщение Anonymous »

У меня возникли проблемы с настройкой конвейера GStreamer для пересылки видеопотока по UDP через OpenCV. У меня есть ноутбук и AGX Xavier, подключенные к одной сети. Идея состоит в том, чтобы перенаправить видеопоток с веб-камеры в AGX, который выполнит некоторую оценку оптического потока OpenCV на графическом процессоре (на Python), нарисует векторы потока на исходном изображении и отправит его обратно на мой ноутбук. До сих пор я могу настроить два конвейера. В качестве минимального примера я создал два сценария bash и сценарий Python, которые в идеале должны функционировать как сквозные объекты OpenCV VideoCapture и VideoWriter.
servevideo.bash:

Код: Выделить всё

#!/bin/bash

gst-launch-1.0 v4l2src device=[device-fd] \
! video/x-raw, width=800, height=600, framerate=24/1 \
! jpegenc ! rtpjpegpay ! rtpstreampay \
! udpsink host=[destination-ip] port=12345
receivevideo.bash:

Код: Выделить всё

#!/bin/bash

gst-launch-1.0 -e udpsrc port=12344 \
! application/x-rtp-stream,encoding-name=JPEG \
! rtpstreamdepay ! rtpjpegdepay ! jpegdec \
! autovideosink
Если я запускаю эти два сценария либо на одном компьютере, либо на двух разных компьютерах в сети, все работает нормально. Когда я добавляю в смесь свой скрипт Python (перечисленный ниже), у меня начинаются проблемы. В идеале я бы запускал сценарии bash на своем ноутбуке с учетом предполагаемых настроек, одновременно запуская сценарий Python на своем Jetson. Тогда я ожидал бы увидеть видео с веб-камеры на своем ноутбуке после объезда Джетсона.
webcam_passthrough.py:
#!/ usr/bin/python3.6

Код: Выделить всё

import cv2

video_in = cv2.VideoCapture("udpsrc port=12345 ! application/x-rtp-stream,encoding-name=JPEG ! rtpstreamdepay ! rtpjpegdepay ! jpegdec ! videoconvert ! appsink", cv2.CAP_GSTREAMER)
video_out = cv2.VideoWriter("appsrc ! videoconvert ! jpegenc ! rtpjpegpay ! rtpstreampay ! udpsink host=[destination-ip] port=12344", cv2.CAP_GSTREAMER, 0, 24, (800, 600), True)

while True:
ret, frame = video_in.read()

if not ret: break

video_out.write(frame)
cv2.imshow('Original', frame)

key = cv2.waitKey(1) & 0xff
if key == 27: break

cv2.destroyAllWindows()
video_out.release()
video_in.release()
С помощью следующего скрипта Python я могу визуализировать кадры через cv2.imshow, полученные из конвейера, настроенного сценарием servevideo.bash. Поэтому я думаю, что моя проблема связана с тем, как я настраиваю Video_out VideoWriter в OpenCV. Я проверил, что мои два сценария bash работают, когда я ретранслирую видеопоток веб-камеры между этими двумя созданными конвейерами, и я проверил, что cv2.VideoCapture получает кадры. Я здесь не эксперт, и мои знания GStreamer практически отсутствуют, поэтому в моем минимальном примере может быть несколько недоразумений. Был бы очень признателен, если бы кто-нибудь из вас указал, чего мне здесь не хватает.
Я также с радостью предоставлю дополнительную информацию, если что-то неясно или отсутствует.
РЕДАКТИРОВАТЬ:
Поэтому кажется, что цель моего минимального примера не была четко выражена.
Три сценария представлены в качестве минимального примера. служат для передачи видео с веб-камеры с моего ноутбука на Jetson AGX Xavier, который затем передает видеосигнал возвращается на ноутбук. Служебноевидео.bash создает на ноутбуке конвейер GStreamer, который использует v4l2 для захвата кадров с камеры и передачи их в сокет UDP. Webcam_passthrough.py запускается на Jetson, где он «подключается» к сокету UDP, созданному конвейером, работающим на ноутбуке. Сценарий Python выполняет транзитную функцию, которая в идеале открывает новый сокет UDP на другом порту и ретранслирует кадры обратно на ноутбук. getvideo.bash создает на ноутбуке еще один конвейер для приема кадров, прошедших через скрипт Python на Jetson. Второй конвейер на ноутбуке используется только для целей визуализации. В идеале этот минимальный пример показывает «необработанный» видеопоток с камеры, подключенной к ноутбуку.
Два bash-скрипта работают изолированно: оба выполняются локально на ноутбуке, а другой — с помощью функции получения видео. bash удаленно на другом компьютере.
Конфигурация cv2.VideoCapture в сценарии Python также работает, поскольку я могу визуализировать кадры (с помощью cv2.imshow< /code>), полученный за UDP-сокет, предоставляемый сценарием servevideo.bash. Это работает как локально, так и удаленно. Часть, которая вызывает у меня некоторую головную боль (я думаю), — это конфигурация cv2.VideoWriter; в идеале это должно открыть сокет UDP, к которому я могу «подключиться» через мой скрипт получения видео.bash. Я тестировал это локально и удаленно, но безрезультатно.
Когда я запускаю getvideo.bash для подключения к UDP-сокету, предоставленному сценарием Python, я получаю следующий вывод:

Код: Выделить всё

Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
Мне это не кажется неправильным, я пробовал запускать различные сценарии с GST_DEBUG=3, что выдавало некоторые предупреждения, но поскольку конфигурации конвейера в сценариях bash в основном одинаковы, для cv2 VideoCapture и VideoWriter я не придаю этим предупреждениям особой ценности. В качестве примера я привел одно такое предупреждение ниже:

Код: Выделить всё

0:00:06.595120595  8962      0x25b8cf0 WARN              rtpjpegpay gstrtpjpegpay.c:596:gst_rtp_jpeg_pay_read_sof: warning: Invalid component
Это предупреждение выводится при постоянном запуске сценария Python с GST_DEBUG=3. Запуск получения видео.bash с тем же уровнем отладки дал:

Код: Выделить всё

Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
0:00:00.013911480  9078 0x55be0899de80 FIXME           videodecoder gstvideodecoder.c:933:gst_video_decoder_drain_out: Sub-class should implement drain()
Setting pipeline to PLAYING ...
New clock: GstSystemClock
Надеюсь, теперь мое намерение стало более ясным, и, как я уже указывал, я считаю, что что-то не так с моим cv2.VideoWriter в скрипте Python, но я не эксперт и GStreamer далек от того, чем я пользуюсь каждый день. Таким образом, я, возможно, что-то неправильно понял.
РЕДАКТИРОВАНИЕ 2:
Итак, теперь я попытался разделить два конвейера на два отдельных процесса, как это предложено @abysslover. Я до сих пор вижу тот же результат и до сих пор понятия не имею, почему это так. Моя текущая реализация сценария Python указана ниже.
webcam_passthrough.py:

Код: Выделить всё

#!/usr/bin/python3.6

import signal, cv2
from multiprocessing import Process, Pipe

is_running = True

def signal_handler(sig, frame):
global is_running
print("Program was interrupted - terminating ...")
is_running = False

def produce(pipe):
global is_running
video_in = cv2.VideoCapture("udpsrc port=12345 ! application/x-rtp-stream,encoding-name=JPEG ! rtpstreamdepay ! rtpjpegdepay ! jpegdec ! videoconvert ! appsink", cv2.CAP_GSTREAMER)

while is_running:
ret, frame = video_in.read()
if not ret: break
print("Receiving frame ...")

pipe.send(frame)

video_in.release()

if __name__ == "__main__":
consumer_pipe, producer_pipe = Pipe()

signal.signal(signal.SIGINT, signal_handler)
producer = Process(target=produce, args=(producer_pipe,))

video_out = cv2.VideoWriter("appsrc ! videoconvert ! jpegenc ! rtpjpegpay ! rtpstreampay ! udpsink host=[destination-ip] port=12344", cv2.CAP_GSTREAMER, 0, 24, (800, 600), True)
producer.start()

while is_running:
frame = consumer_pipe.recv()
video_out.write(frame)
print("Sending frame ...")

video_out.release()
producer.join()
Конвейер, который я создал между двумя процессами, как и ожидалось, предоставляет новый кадр. Когда я пытаюсь прослушать UDP-порт 12344 с помощью netcat, я не получаю ничего такого же, как раньше. Мне также трудно понять, насколько сильно меняется дифференциация конвейеров, поскольку я ожидаю, что они уже будут работать в разных контекстах. Тем не менее, я могу ошибаться в этом предположении.

Подробнее здесь: https://stackoverflow.com/questions/660 ... -gstreamer
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»