Я читаю камеру в конвейере 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 не заботится о нечистом отключении.