OpenCV+FFmpeg 实现人脸检测Rtmp直播推流(Python快速实现)

news2024/9/25 10:39:38

实现效果

windows平台笔记本摄像头视频采集、人脸识别,识别后将视频推流到RTMP流媒体服务器,在任意客户端可以进行RTMP拉流播放。

效果如图:
在这里插入图片描述

使用VLC播放器进行拉流。

准备工作

需要先安装OpenCV的python包以及FFmpeg。

对于ffmpeg有两种调用方式,但这两种方式都需要先安装ffmpeg,调用的具体区别是:

  • 使用管道通信的方式,调用FFmpeg可执行文件,通过管道写入视频帧数据,交给FFmpeg编码、推流;
  • 也可以安装ffmpeg-python包,这个包封装了对FFmpeg的调用,最终也是通过管道通信实现数据传递的。

推荐直接用第一种方式。

人脸检测实现

首先要区分说明一下,人脸检测与人脸识别是不一样的。检测只是将图像中的人脸框出或作其他突出显示,人脸识别则需要预先将人脸录入,当图像、视频中出现人脸时,对人脸进行检测,再将得到数据与录入的进行匹配,识别判断,人脸考勤机是人脸识别最常见的应用。

因此,人脸识别要比人脸检测更复杂一些。

利用Python opencv的Haar特征检测,可以很方便实现人脸检测的效果。

示例代码:

import cv2

# 人脸检测器模型文件路径
# face_cascade = cv2.CascadeClassifier('C:/Users/ACER/AppData/Local/Programs/Python/Python37/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml') #pip安装opencv包路径下的模型文件
face_cascade = cv2.CascadeClassifier('D:/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml')
# 打开摄像头
cap = cv2.VideoCapture(0)

while True:
    # 读取一帧
    ret, frame = cap.read()

    # 将图片转换为灰度图像
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # 检测人脸
    faces = face_cascade.detectMultiScale(gray, 1.3, 5)

    # 在检测到的每张人脸周围画一个矩形
    for (x,y,w,h) in faces:
        cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)

    # 显示帧
    cv2.imshow('frame',frame)

    # 如果按下q键,退出循环
    if cv2.waitKey(1) & 0xFF == 27:
        print("Press Esc, to exit.")
        break

# 释放摄像头
cap.release()

# 关闭所有窗口
cv2.destroyAllWindows()

代码流程:

  • 构建一个Haar级联分类器,调用CascadeClassifier即可,传入的参数为人脸检测器模型文件路径:

    cv2.CascadeClassifier('C:/Users/ACER/AppData/Local/Programs/Python/Python37/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml')
    cv2.CascadeClassifier('D:/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml')
    

    可以使用pip安装opencv包的路径下的模型文件,也可以使用自己安装的opencv中的模型文件,效果相同。

    'C:/Users/ACER/AppData/Local/Programs/Python/Python37/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml'是使用pip安装opencv-python时下载的;

    'D:/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml'则是我自己安装opencv库时下载的。

  • 调用VideoCapture采集视频帧,并将其转为灰度图,传递给人脸级联分类器face_cascade;

  • 得到分类后的矩形坐标后,在原有数据上绘制出矩形框,即可将人脸框出,调用imshow方法将处理后的图像显示。

调用FFmpeg实现RTMP推流

前面说了有两种方式。

1、直接调用ffmpeg命令

实现思路:调用FFmpeg,在后台开一个子进程,视频帧数据通过这个子进程标准输入写入,数据经过子进程处理后推流到RTMP服务器。

ffmpeg安装后需要添加到windows环境变量,确保在命令行可以直接调用。

import cv2
import subprocess
# 打开摄像头
cap = cv2.VideoCapture(0)

# 设置摄像头分辨率
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
cap.set(cv2.CAP_PROP_BUFFERSIZE, 2)

fps = cap.get(cv2.CAP_PROP_FPS)
print("fps:", fps)
# 设置缓冲区大小为2

# 定义视频编码器
fourcc = cv2.VideoWriter_fourcc(*'X264')

# 创建FFmpeg命令行参数
ffmpeg_cmd = ['ffmpeg',
              '-y',  # 覆盖已存在的文件
              '-f', 'rawvideo',
              '-pixel_format', 'bgr24',
              '-video_size', '640x480',
              '-i', '-',  # 从标准输入读取数据
              '-c:v', 'libx264', #使用x264编码器
              '-preset', 'ultrafast',
              '-tune', 'zerolatency',#零延迟
              '-pix_fmt', 'yuv420p',
              '-f', 'flv',
              'rtmp://120.79.54.142:1935/live/cv_demo']

# 启动FFmpeg进程
ffmepg_process = subprocess.Popen(ffmpeg_cmd, stdin=subprocess.PIPE)
# 开始采集和推流
while True:
    # 采集一帧图像
    ret, frame = cap.read()
    if ret:
        # 通过FFmpeg编码和推流
        ffmepg_process.stdin.write(frame.tobytes())

# 停止FFmpeg进程并释放资源
ffmepg_process.stdin.close()
ffmepg_process.wait()
cap.release()

2、使用ffmpeg-python包

chatgpt给出的示例,存在一些小问题,没有使用这种方式,暂未深究。

import cv2
import ffmpeg

# 打开本地摄像头
cap = cv2.VideoCapture(0)

# 设置编码参数
output_size = (640, 480)
fps = 30
codec = "libx264"
bitrate = "1000k"

# 设置输出流
rtmp_url = "rtmp://your-rtmp-server-url.com/live/stream_key"
out = ffmpeg.output(
    ffmpeg.input('pipe:', format='rawvideo', pix_fmt='bgr24', s='{}x{}'.format(*output_size), r=fps),
    ffmpeg.format('flv'),
    rtmp_url,
    vcodec=codec,
    b=bitrate
)

# 打开输出流
process = out.run_async(pipe_stdin=True)

# 循环读取每一帧图像,并将其写入输出流
while True:
    ret, frame = cap.read()
    if not ret:
        break
    process.stdin.write(frame.tobytes())

# 关闭输入流和输出流
cap.release()
process.stdin.close()
process.wait()

拉流验证

推流成功后,可以使用VLC播放器拉流验证,使用网络串流功能,输入推流的url,播放即可。

在这里插入图片描述

狗头是自己加的:)。

视频采集+人脸检测+RTMP推流

将上面的两个例子组合一下,即可实现。

人生苦短,我用Python,直接上代码:

import cv2
import ffmpeg
import subprocess

# 人脸检测器
class FaceDetector:
    def __init__(self, module_file):
        self.module_file = module_file
        self.face_cascade = cv2.CascadeClassifier(self.module_file)

    def detectFace(self, gray_img):
        face_rect = self.face_cascade.detectMultiScale(gray_img, 1.3, 5)
        return face_rect
# 推流器
class StreamPusher:
    def __init__(self, rtmp_url):
        # 创建FFmpeg命令行参数
        ffmpeg_cmd = ['ffmpeg',
                      '-y',  # 覆盖已存在的文件
                      '-f', 'rawvideo',
                      '-pixel_format', 'bgr24',
                      '-video_size', '640x480',
                      '-i', '-',  # 从标准输入读取数据
                      '-c:v', 'libx264',
                      '-preset', 'ultrafast',
                      '-tune', 'zerolatency',
                      '-pix_fmt', 'yuv420p',
                      '-f', 'flv',
                      rtmp_url]
        print('ffmpeg_cmd:', ffmpeg_cmd)
        # 启动 ffmpeg
        self.ffmepg_process = subprocess.Popen(ffmpeg_cmd, stdin=subprocess.PIPE)

    def streamPush(self, frame):
        self.ffmepg_process.stdin.write(frame.tobytes())

# 人脸检测器模型文件路径
module_file = 'D:/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml'
rtmp_server = 'rtmp://120.79.54.142:1935/live/cv_demo'

# program entry
if __name__ == '__main__':
    dectector = FaceDetector(module_file)
    pusher = StreamPusher(rtmp_server)
    # 打开摄像头
    cap = cv2.VideoCapture(0)
    while True:
        # 读取一帧
        ret, frame = cap.read()
        # 将图片转换为灰度图像
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # 检测人脸
        faces = dectector.detectFace(gray)
        # 在检测到的每张人脸周围画一个矩形
        for (x,y,w,h) in faces:
            cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
        # 显示帧
        cv2.imshow('frame',frame)
        # 如果按下Esc键,退出循环
        if cv2.waitKey(1) & 0xFF == 27:
            print("Press Esc, to exit.")
            break
        pusher.streamPush(frame)
    # 释放摄像头
    cap.release()
    # 关闭所有窗口
    cv2.destroyAllWindows()

总结

使用python可以快速实现功能,但延迟还是有点高,画面也不太流畅,还有优化空间。有空还是用CPP实现一下吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/430592.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java——删除链表中重复的节点

题目链接 牛客在线oj题——删除链表中重复的节点 题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表 1->2->3->3->4->4->5 处…

【Vue】学习笔记-数据代理

数据代理 Object.defineproperty方法 <script type"text/javascript">let number18let person{name:张三,sex:男,}//age属性 不参与遍历Object.defineProperty(person,age,{//value:18,//enumerable:true, //控制属性是否可以枚举&#xff0c;默认值是false//…

科技成果评价最新攻略,你确定不来看看?

一、什么是科技成果评价&#xff1f; 是指按照委托者的要求&#xff0c;由具有评价资质的第三方专业机构聘请专家&#xff0c;坚持实事求是、科学民主、客观公正、注重质量、讲求实效的原则&#xff0c;依照规定的程序和标准&#xff0c;对被评价科技成果进行审查与辨别&#…

[Java Web]VUE | vue:一项Java Web开发中不可或缺的前端技术

⭐作者介绍&#xff1a;大二本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;努力输出优质文章 ⭐作者主页&#xff1a;逐梦苍穹 ⭐所属专栏&#xff1a;Java Web ⭐如果觉得文章写的不错&#xff0c;欢迎点个关注一键三连&#x1f609;有写的不好的地方也欢迎指正&a…

AD19 基础应用技巧(快速定义PCB板框,CAD中DWG转DXF格式导入)

【B站一个假的攻城狮】导入CAD图纸到PCB&#xff0c;Altium Designer 21教程&#xff0c;第九节。 http://www.keyboard-layout-editor.com/ http://builder.swillkb.com/ 1、打开中望CAD&#xff0c;并打开一张图纸文件&#xff0c;为了能把孔表达清楚&#xff0c;开孔断面图…

React(六) —— redux

&#x1f9c1;个人主页&#xff1a;个人主页 ✌支持我 &#xff1a;点赞&#x1f44d;收藏&#x1f33c;关注&#x1f9e1; 文章目录⛳Redux&#x1f346;redux定义&#x1f490;redux使用原则&#x1f370;redux使用场景&#x1f9ca;redux工作流程&#x1f96b;redux基本创建…

14.创建组件

组件可以理解为页面的拼图块&#xff0c;一个完整的页面是由若干个组件拼成的 在vue中规定&#xff0c;组件的后缀名为vue&#xff0c;每一个vue文件中应该包含三个大标签 template 组件的模板结构&#xff0c;可以理解为htmlscript 组件的JS&#xff0c;控制组件要执行什么动…

区域检验管理系统(云LIS)源码

1、区域检验管理系统&#xff08;云LIS&#xff09;概述 云LIS是为区域医疗提供临床实验室信息服务的计算机应用程序&#xff0c;可协助区域内所有临床实验室相互协调并完成日常检验工作&#xff0c;对区域内的检验数据进行集中管理和共享&#xff0c;通过对质量控制的管理&am…

Java每日一练(20230418)

目录 1. N皇后 II &#x1f31f;&#x1f31f;&#x1f31f; 2. 字符串相乘 &#x1f31f;&#x1f31f; 3. 买卖股票的最佳时机 &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一…

“Natural Earth II“ === “Natural Earth II“是false?你知道空 格的四种写法吗?

前言 有一回对我说道&#xff0c;“你学过前端么&#xff1f;”我略略点一点头。他说&#xff0c;“学过前端&#xff1f;……我便考你一考。html 里面的空格&#xff0c;怎样 coding 的&#xff1f;”我想&#xff0c;讨饭一样的人&#xff0c;也配考我么&#xff1f;便回过脸…

计算机网络 - 网络中的基本概念

前言 本篇介绍网络的一些基本概念&#xff0c;认识IP地址&#xff0c;端口号&#xff0c;协议&#xff1b;了解常用的网络协议模型&#xff0c;知道数据如何封装与分用的&#xff1b;为以后学习计算机网络其它知识做铺垫&#xff0c;如有错误&#xff0c;请在评论区指正&#…

Java数据结构 二叉树基本知识 二叉树遍历

二叉树很简单的&#xff0c;试试呗~ 文章目录 Java数据结构 & 二叉树基本知识 & 二叉树遍历1. 树的基本定义2. 树的基本概念2.1 例子2.2 树的代码表示&#xff1a; 3. 二叉树3.1 特殊节点3.2 特殊的二叉树3.3 二叉树的性质3.3.1 证明第三点3.3.2 证明第四点 4. 二叉树遍…

MySQL-MHA高可用(一)

目录 &#x1f341;同步概念 &#x1f341;工作原理 &#x1f343;环境拓扑 &#x1f341;环境准备 &#x1f342;manager &#x1f342;master1 &#x1f342;master2 &#x1f342;slave &#x1f343;配置半同步复制 &#x1f341;master1 &#x1f341;master2 &#x1f34…

函数 tcgetpgrp tcsetpgrp 和 tcgetsid

① tcgetpgrp & tcsetpgrp 函数 tcgetpgrp函数是用来获取前台进程组的ID #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> int main() {printf("我的ID&#xff1a;%d---我…

【MySQL学习】MySQL库的操作

目录一、查看数据库的连接二、数据库的创建三、字符集和校验规则3.1 查看数据库默认的字符集以及校验规则3.2 查看数据库支持的字符集以及校验规则3.3 校验规则对数据库的影响四、操纵数据库4.1 查看数据库4.2 显示创建语句4.3 修改数据库4.4 数据库的删除五、数据库的备份与恢…

Nginx中的location规则与rewrite

nginx正则表达式 ^$空行 \d数字 \D代表非数字 \s 匹配空白符 \S 非空白字符 \w匹配任意单词符包括下划线[A-Za-z0-9_] {n} 匹配起那面字符n次 .* 除换行符\n匹配任意字符多次 {n,m}匹配前面字符5到10次 [abc] 匹配一次a,b,c ( )表达式的开始和结束 | 或运算符 &#…

【uniapp】sigmob广告加载失败:-5005、500422没有imei的解决办法(原创可用)

问题 最近打算将开发的uniapp应用对接uni-ad广告中去&#xff0c;在对接sigmob的时候出现了以下问题&#xff1a;①错误码-5005&#xff0c;查询了以下官方文档&#xff0c;发现是说我频繁调用&#xff0c;可是并没有&#xff0c;我是在真机上测试的没成功就没在弄了&#xff…

【力扣-876】链表的中间结点

&#x1f58a;作者 : Djx_hmbb &#x1f4d8;专栏 : 数据结构 &#x1f606;今日分享 : ----------小Tips&#xff1a; 虽然都是口服液体制剂&#xff0c;且看起来单支容量都一样&#xff0c;但是“藿香正气水”与“藿香正气口服液”的区别你知道吗&#xff1f;藿香正气水里含有…

Vue电商项目实战之角色列表添加,编辑,删除功能

这是黑马vue电商项目后台,自己需要完成的功能,这里仅供参考当然还需要自己去理解. 一.添加功能 在roles.vue中 1.添加角色的对话框 代码如下: <!-- 添加角色的对话框 --><el-dialog :visible.sync"addRoleDialogVisible" title"添加角色" widt…

【C++技能树】原来比C方便这么多 --缺省参数、函数重载、引用讲解

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…