Как можно определить формат изображения из потока байтов?

#python #opencv #udp #python-imaging-library

#python #opencv #udp #python-imaging-library

Вопрос:

Я пытаюсь написать скрипт на python, который присоединяется к групповой рассылке веб-камеры и сохраняет каждый полученный кадр в виде изображения на локальном жестком диске. Обычно можно щелкнуть ссылку на поток, и поток воспроизводится в браузере или в VLC media player.

Поток предоставляется в виде многоадресной рассылки UDP, на которую я могу подписаться с помощью следующего кода (Python33, Windows 7):

 import socket
import struct

MCAST_GRP = '(the ip)'
MCAST_PORT = (the port)

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', MCAST_PORT))
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)

sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)


while True:
    data = sock.recv(1316)

    print(data)
  

Вот где я застрял. данные, по-видимому, представляют собой поток байтов, в котором, я надеюсь, закодировано изображение, но, не зная наверняка, в каком формате находится изображение, у меня возникают проблемы с декодированием этого потока и превращением его в реальное изображение. Данные печати показывают выходные данные такого рода:

b’G x01 x00 x1c xc4 …’ b’G x01 x00 x18 x87 …’ b’GA x015p x00 xff xff …’

Как я могу преобразовать эти потоки байтов в фактическое изображение? Существуют ли маркеры, связанные с форматами jpg / png, которые мне нужно искать и изолировать?

Заранее спасибо за помощь!

Комментарии:

1. Вы можете взглянуть на эту библиотеку: pythonware.com/products/pil

2. Пробовал использовать ImageFile. Parser().feed(данные), но я получаю сообщение об ошибке: IOError(‘невозможно проанализировать это изображение’). Может быть, мне сначала нужно декодировать или изолировать, где фактическое изображение находится в потоке?

3. Кроме того, я использовал VLC, чтобы выяснить, что он использует кодек H264 — MPEG-4 AVC для декодирования этого потока.

Ответ №1:

Если в потоке также есть заголовок файла (изображения), он содержит информацию о формате, например, см. wiki для формата файла BMP

Ответ №2:

Я не эксперт по python, но немного эксперт по потоковой передаче видео, и я подозреваю, что вы с самого начала могли подумать об этом неправильно. Когда вы присоединяетесь к многоадресной рассылке и получаете поток, это имеет мало общего со статическими изображениями. Видео обычно кодируется в соответствии со стандартом H.264, а кадры структурируются в так называемую группу изображений (GOP). GOP состоит из I, P и B кадров, например IPBBBBBBBBBPBPI, из которых статические изображения являются только I кадрами. Обычно I-фреймы хранятся в виде изображений меньшего размера, чтобы отображать их во время операций FF или RW. Для извлечения I кадров из видеопотока вы обычно используете автономную библиотеку, и наиболее полезную, которую я знаю — https://www.ffmpeg.org /

Это позволит вам декодировать поток до всех 24,25 или любого другого количества кадров каждую секунду, на случай, если вы действительно хотите сохранить каждое изображение в видео…

Комментарии:

1. Спасибо за фантастический ответ и правильное определение моего непонимания. Сейчас я использую OpenCV (вызываемый из python) для декодирования потока. Насколько я понимаю — я могу ошибаться — opencv использует ffmpeg для декодирования потока. Знаете ли вы, хорош ли ffmpeg для декодирования формата MPEG-4 Part 10 AVC? VLC открывается и показывает поток без каких-либо проблем, но мое решение opencv показывает фрагментированные изображения (почти как некоторая информация не поступает, и одни и те же пиксели повторяются для завершения изображения).

2. ну, H.264 и AVC в основном synonyms:en.wikipedia.org/wiki/H.264/MPEG-4_AVC — значит, ffmpeg справляется с этим. Используете ли вы ffmpeg или что-либо еще, вам нужно декодировать (или распаковывать) видео, чтобы получить только I кадров (фактические изображения). Может быть, посмотрите здесь, чтобы проверить, как это работает pr0gr4mm3r.com/linux /…