Правильное закрытие файла конвейера gstreamer, используемого в OpenCV VideoCapture - PullRequest
0 голосов
/ 04 апреля 2019

Я читаю камеру в конвейере GStreamer на NVidia TX2.Я хочу, чтобы вывод был закодирован в h264 и записан в файл.Кроме того, я хочу, чтобы в OpenCV были доступны кадры для дальнейшей обработки.

Для этого я создал следующий конвейер, который работает с использованием gst-launch:

gst-launch-1.0 nvcamerasrc sensor-id=0 ! \
'video/x-raw(memory:NVMM), width=(int)1920, height=(int)1280, 
format=(string)I420, framerate=(fraction)30/1' ! tee name=t \
t. ! queue! omxh264enc ! 'video/x-h264, stream-format=(string)byte-stream' ! \
h264parse ! qtmux ! \
filesink location=test.mov \
t. ! queue! nvvidconv ! video/x-raw ! xvimagesink -e

Это все работаети нет никаких проблем с этим конвейером.Он показывает кадры на экране (эта часть будет заменена на appink в OpenCV) и создается подвижный файл, который можно воспроизвести.

Обратите внимание на «-e» в конце команды.Чтобы остановить запись, я нажимаю Ctrl-C.Если я пропущу "-e", я получу испорченный фильм, который нельзя воспроизвести.Это также имеет смысл при проверке man-страницы для gst-launch-1.0, так как в ней конкретно упоминается этот случай.

Нет, когда я переводю это в OpenCV в Python, я получаю следующее:

import cv2

pipeline = ("nvcamerasrc sensor-id=0 ! "
        "video/x-raw(memory:NVMM), width=(int)640, height=(int)360, format=(string)I420, framerate=(fraction)30/1 ! tee name=t "
        "t. ! queue! omxh264enc ! video/x-h264, stream-format=(string)byte-stream ! "
        "h264parse ! qtmux ! "
        "filesink location=test.mov "
        "t. ! queue! nvvidconv ! video/x-raw, format=(string)BGRx ! "
        "videoconvert ! video/x-raw, format=(string)BGR ! appsink")


vc1 = cv2.VideoCapture(pipeline, cv2.CAP_GSTREAMER)
while(True):
    _, vc1_f = vc1.read()

    cv2.imshow('vc1', vc1_f)
    if not cv2.waitKey(1) == -1:
        break

vc1.release()
cv2.destroyAllWindows()

Это также работает нормально без каких-либо ошибок, единственное, что происходит, это то, что я получаю поврежденный файл фильма при выходе.Точно так же, как если бы вы пропустили опцию «-e» в версии gst-launch.

Во всем этом я понимаю, что немного неправильно использую VideoCapture, потому что это обычно не используется для записифайлы, но только для получения кадров в OpenCV через элемент appsink.Здесь, однако, он также используется для записи файла напрямую с использованием конвейера gstreamer.

Я, конечно, могу создать отдельный конвейер:

"appsrc ! videoconvert ! omxh264enc ! h264parse ! qtmux ! filesink location=test.mov "

и передать обратно полученные кадрыв OpenCV, используя VideoWriter (я тестировал это, и он работает должным образом), но это создает некоторые накладные расходы, поэтому я предпочел бы не делать этого и поддерживать его в чистоте и придерживаться моего единственного конвейера VideoCapture.

В общем, мой вопрос: возможно ли то, что я хочу здесь сделать?Или я просто слишком злоупотребляю VideoCapture?Т.е. есть ли Python OpenCV, эквивалентный опции "-e" gst-launch для VideoCapture, потому что VideoCapture :: release () не выполняет эту работу.

Спасибо!

РЕДАКТИРОВАТЬ

Не нашел правильного решения (форум OpenCV подтвердил его не существует), но решил сохранить только поток H264 и исключить мультиплексирование изконвейер и сделайте это потом отдельно, используя ffmpeg.Поток H264 не заботится о нечистом отключении.

...