Передать поток ffmpeg в OpenCV

Я хотел бы использовать оператор перенаправления для переноса потока из ffmpeg в cv2, чтобы я мог распознавать или отмечать лица в потоке и снова перенаправлять этот поток, чтобы он работал под другим потоком.

Один без распознавания лиц и один без распознавания лиц.

      raspivid -w 1920 -h 1080 -fps 30 -o - -t 0 -vf -hf -b 6000000 | ffmpeg -f h264 -i - -vcodec copy -g 50 -strict experimental -f tee -map 0:v "[f=flv]rtmp://xx.xx.xx.xx/live/withoutfacedetect |[f=h264]pipe:1" > test.mp4

Затем я прочитал CV2 и наткнулся на статью.

https://www.bogotobogo.com/python/OpenCV_Python/python_opencv3_Image_Object_Detection_Face_Detection_Haar_Cascade_Classifiers.php

Затем я запустил сценарий со своей фотографией и был очень удивлен, что вокруг моего лица появился квадрат.

Но теперь вернемся к делу. Как лучше всего это сделать?

спасибо @Mark Setchell, забыл упомянуть, что я использую Raspberry Pi 4.

1 ответ

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

Хорошо, видеопоток поступает с камеры в Raspberry Pi изначально как RGB или YUV. Кажется глупым использовать для кодирования этого в h264, передавать его в OpenCV, когда AFAIK, OpenCV не может легко декодировать его обратно в BGR или что-нибудь, с чем он, естественно, любит обнаруживать лица.

Итак, я думаю, что я бы изменил параметры на raspivid так что он генерирует кадры данных RGB и удаляет весь битрейт h264, т.е.

      raspivid -rf rgb  -w 1920 -h 1080 -fps 30 -o - | ffmpeg ...

Теперь у нас есть RGB, входящий в ffmpeg, поэтому вам нужно использовать tee а также map похоже на то, что у вас уже есть, и отправьте RGBв OpenCV и h264-кодировать второй поток в rtmp как у вас уже есть.

Затем в OpenCV вам просто нужно сделать read()от 1920x1080x3 байтов для получения каждого кадра. Рамка будет в RGB, но вы можете использовать:

      cv2.cvtColor(cv2.COLOR_RGB2BGR)

чтобы переупорядочить каналы в BGR, как того требует OpenCV .

Когда вы читаете данные из stdin вам нужно сделать:

      frame = sys.stdin.buffer.read(1920*1080*3)

скорее, чем:

      frame = sys.stdin.read(1920*1080*3)

который искажает двоичные данные, такие как изображения.

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