Как наиболее эффективно отправить непрерывный поток кадров на сервер - PullRequest
1 голос
/ 27 апреля 2019

Я пытаюсь отправить кадры с локальной камеры (камера raspberry pi, но также может быть веб-камерой моего ноутбука) в облачный экземпляр Google, на котором я выполняю обработку кадров AI.

Iмне удается отправлять кадры, снятые через opencv через http (т.е. tcp ??), и получать их на флеш-сервер.Когда флеш-сервер работает локально, я могу получить хорошие fps (50+ fps для размера изображения 640x480), однако, как только я отправляю кадры в приложение фляги на экземпляре google, fps резко падает до ~ 5fps.

Как я сейчас отправляю кадры:

while True:
        frame = vs.read() #Separate thread, using cv2 to get the frame

        ret, jpeg = cv2.imencode('.jpg', frame)
        imgdata = jpeg.tobytes()
        response = requests.post(
            url='http://<IP address of google instance>:<port>',
            data= imgdata,
            headers={'content-type':'image/jpeg'},
            )

Я вижу две проблемы с этим: 1 - использование tcp означает, что я медленнее протокола udp, однако размер udp ограничен в байтах.Поправьте меня, если я ошибаюсь, но кажется очень сложным посылать усеченные кадры и снова собирать их на сервере. 2 - Даже если у меня работает udp, сжатие кадров не происходит, поэтому я никогда не достигну эффективной передачи

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

Есть какие-нибудь рекомендации по поводу лучшего пути вперед?

1 Ответ

2 голосов
/ 27 апреля 2019

Правильный выбор протокола для вашего случая - TCP. UDP не гарантирует, что данные будут доставлены в правильном порядке и не повреждены. UDP не будет быстрее, чем TCP в вашем случае (если вы убедитесь, что данные не повреждены и находятся в порядке в вашем коде).

Вы уже сжимаете изображения, конвертируя их в jpg. Дополнительное сжатие было бы действительно неэффективно. И TCP, и UDP не сжимают данные при передаче.

Я считаю, что сейчас вы несколько ограничены библиотекой requests и кодированием данных в протокол HTTP. Вы должны рассмотреть возможность использования чистого TCP без издержек HTTP. Это можно сделать с помощью модуля socket в стандартной библиотеке Python. Однако у вас, вероятно, все равно будет низкая производительность, потому что у вас нет межкадрового сжатия и только внутрикадровое сжатие. Вам следует рассмотреть возможность использования ffmpeg для сжатия данных с вашей камеры и отправки потока через TCP с вашей программой или с помощью потоковой передачи точки 2 ffmpeg .

...