Захват одиночного изображения из видеопотока H.264 с поддержкой протокола RTSP - PullRequest
0 голосов
/ 07 февраля 2019

Я пытаюсь захватить одно изображение по требованию из видеокадра RTSP H.264.Я использую OpenCV с Python, работающим на Raspberry Pi.

Насколько я понимаю, вы не можете просто захватить изображение, а должны постоянно читать поток изображений из видео и отбрасывать все, кроме случайного, которое вы хотите.Это очень дорого в вычислительном отношении и потребляет около 25% ЦП на Pi, чтобы ничего не делать, кроме как читать и отбрасывать 12.2x720 15 кадров / с видеокадры H.264 rtsp.

Есть ли другой способ?Я гибок и могу также использовать GStreamer, FFMPEG или что-нибудь еще, что является более эффективным в вычислительном отношении.

Ответы [ 3 ]

0 голосов
/ 07 февраля 2019

Я делал что-то подобное.Вот мой код:

def CaptureFrontCamera():
    _bytes = bytes()
    stream = urllib.request.urlopen('http://192.168.0.51/video.cgi?resolution=1920x1080')
    while True:
        _bytes += stream.read(1024)
        a = _bytes.find(b'\xff\xd8')
        b = _bytes.find(b'\xff\xd9')
        if a != -1 and b != -1:
            jpg = _bytes[a:b+2]
            _bytes = _bytes[b+2:]
            filename = '/home/pi/capture.jpeg'
            i = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
            cv2.imwrite(filename, i)
            return filename
0 голосов
/ 03 марта 2019

Чтобы ответить на мой собственный вопрос.Вместо использования read ():

cap = cv2.VideoCapture('rtsp_url')

def captureimages():
    while True:
        image = cap.read()

s = threading.Thread(target=captureimages)
s.start()

if takepic == True:
    picture = image.copy()

Более эффективно разбить его на grab () и retrieve ().Не идеальное решение, но лучше:

cap = cv2.VideoCapture('rtsp_url')

def captureimages():
    while True:
        cap.grab()

s = threading.Thread(target=captureimages)
s.start()

if takepic == True:
    picture = cap.retrieve()
0 голосов
/ 07 февраля 2019

Причина, по которой вы должны прочитать поток, состоит в том, что H.264 имеет несколько видов кадров (см. https://en.wikipedia.org/wiki/Video_compression_picture_types), а кадры P и B требуют декодирования контекста. Только I-кадры (также известные как ключевыекадры) могут быть декодированы автономно.

Если вы хотите читать действительно произвольные кадры, вы можете анализировать (не декодировать) поток и сохранять все, начиная с последнего I-кадра. Когда ваш триггер приходит, вы декодируете поток, так какпоследний I-кадр и до текущей точки.

Если вам не нужно быть очень точным, вы можете просто сохранить последний I-кадр и декодировать его по требованию. Это будет очень быстро, но этоозначает, что вы можете получить изображение не в то время.

Наконец, как часто появляются эти ключевые кадры? Это зависит от источника. Например, веб-камера C920 генерирует их примерно каждые 5 секунд по умолчанию, но этот интервал можетбыть изменено с 1 до 30 секунд (я думаю, это было некоторое время назад)

...