преобразовать необработанные данные yuv420p в изображение opencv

У меня есть необработанные данные с сервера rtmp с форматом пикселей yuv420p

Я использую канал для чтения данных. Но я не знаю, как декодировать необработанные данные в изображение.

command = ['ffmpeg']
command.extend(["-loglevel", "fatal", "-i", 'rtmp://localhost/live/stream', "-f", "flv", "-pix_fmt" , 'yuv420p', '-vcodec', 'h264', "-"])
self.process = subprocess.Popen(command, stderr=subprocess.PIPE ,stdout = subprocess.PIPE)
self.output = self.process.stdout
self.fs = width*height*3 // 2
while True:
    data = self.output.read(self.fs)

Я попытался декодировать, как это, введите описание ссылки здесь

Но результат - введите описание изображения здесь

Может ли кто-нибудь помочь мне с этой проблемой?

1 ответ

Решение

Я не специалист по ffmpeg, поэтому я обращусь к любому, кто знает лучше, и удалю свой ответ, если он окажется неверным.

Насколько я понимаю, у вас есть поток RTMP, который вы хотите вставить в OpenCV. OpenCV использует массивы Numpy с упорядочением BGR для хранения изображений - и, очевидно, видеокадров, которые представляют собой просто множество изображений, одно за другим. Итак, я предлагаю вам спросить ffmpeg чтобы преобразовать видеопоток Flash в именно то, что хочет OpenCV:

       ffmpeg <RTMP INPUT STUFF> -pix_fmt bgr24 -f rawvideo -

а затем измените это, поскольку теперь это BGR888:

       self.fs = width * height * 3

Поскольку у меня нет доступного источника RTMP, я создал такой тестовый поток:

       # Generate raw video stream to read into OpenCV    
ffmpeg -f lavfi -i testsrc=duration=10:size=640x480:rate=30 -pixel_format rgb24 -f rawvideo -

И затем я отправил это в Python с помощью:

       ffmpeg -f lavfi -i testsrc=duration=10:size=640x480:rate=30 -pixel_format rgb24 -f rawvideo - | ./PlayRawVideo

Программа Python PlayRawVideo выглядит так:

       #!/usr/bin/env python3

import numpy as np
import cv2
import sys

# Set width and height
w, h = 640, 480

while True:
    data = sys.stdin.buffer.read(w * h *3)
    if len(data) == 0:
        break
    frame = np.frombuffer(data, dtype=np.uint8).reshape((h, w, 3))
    cv2.imshow("Stream", frame)
    cv2.waitKey(1)
    

Обратите внимание, что мне пришлось использовать sys.stdin.buffer.read() чтобы получить необработанные двоичные данные.

Другие вопросы по тегам