Передать поток 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 и наткнулся на статью.
Затем я запустил сценарий со своей фотографией и был очень удивлен, что вокруг моего лица появился квадрат.
Но теперь вернемся к делу. Как лучше всего это сделать?
спасибо @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)
который искажает двоичные данные, такие как изображения.