Вернёмся к корням. Питон же скриптовый язык. И есть же pipes. Ну, знаете, cat big_file | more. Можно заставить FFmpeg фигачить картинки в stdout и засасывать их в питон через трубу. Благо для этого есть subprocess. Оно, конечно, небыстро – использование FFmpeg в виде библиотеки в 2-3 быстрее. Но всё относительно. Допустим, мне удастся снизить время засасывания кадра с 1 мс до 0.3 мс. В три раза! И кадр будет обрабатываться не 101 мс, а всего-то 100.3 мс. Ну, вы поняли. Итак, FFmpeg через RTSP тянет с камеры поток и выдаёт ч/б картинки. Почему ч/б? Потому, что алгоритмам цвет не нужен и всё равно преобразовывать в gray8. А вот гонять через трубы и в памяти хранить в три раза меньше. Минутка математики: кадр 1280х720 в цвете весит 2,7 мегабайта, а в ч/б – 900 килобайт. Если исходить из того, что 6 ГБ памяти под это не жалко, то получается 2330 цветных кадров или 7000 ч/б. После получения кладём кадр в буфер на 25 кадров. Это позволит нам немного, на секунду, заглянуть в прошлое и компенсировать задержки. А поскольку 99% этих кадров не будут востребованы, то обработку делаем при поступлении с камеры сигнала движения. Да и трубы надо читать БЫСТРО, поскольку один переполненный пайп блокирует вообще всё. Результат кладём в очередь на детектирование лиц. Максимальный размер этой очереди мы уже посчитали. Ну, на самом-то деле я пару раз загнал машину в мёртвый своп, а уж потом посчитал и ограничил размер очереди. Не повторяйте моих ошибок. Дальше разгребаем очередь, при необходимости определяя и тела. Результаты складываем в пригодном для передачи в другой процесс виде в выходную очередь. Архитектура! Немало крови стоил мне следующий нюанс: ВСЕГДА при работе с ЛЮБЫМИ очередями на питоне используйте timeout. Типа, det_q.get(timeout=5). То есть, повисели на get, отвалились по таймауту, снова повисли на get. Иначе в недрах питона обязательно случится какой-нибудь deadlock #Jarvis
Комментариев нет:
Отправить комментарий