使用YOLOv3进行实时活体检测:Python与OpenCV实现

news2024/12/1 14:33:04

目录

  1. 引言
  2. 准备工作
    • 安装必要的库
    • 下载模型文件
  3. 代码解析
    • 导入库
    • 参数设置
    • 加载YOLOv3模型
    • 摄像头初始化
    • 图像处理和目标检测
    • 运动检测逻辑
    • 调试信息显示
  4. 运行示例
  5. 总结
  6. 参考资料

1. 引言

在现代安全监控系统中,能够区分视频流中的活体(如人)与其他物体的能力至关重要。这种能力不仅有助于提高系统的准确性和效率,还能在一定程度上减少误报。本文将介绍如何使用YOLOv3(You Only Look Once version 3)这一先进的对象检测算法,结合OpenCV库来实现一个简单的实时活体检测系统。我们将详细解析整个过程,并提供完整的Python代码。

2. 准备工作

安装必要的库

首先,确保你的环境中安装了以下库:

  • OpenCV: 用于图像处理和摄像头操作。
  • NumPy: 提供高效的数值运算支持。

可以通过pip命令安装这些库:

pip install opencv-python numpy

下载模型文件

YOLOv3需要配置文件(.cfg)、权重文件(.weights)以及类别名称文件(.names)。这些文件可以从YOLO官方网站下载。对于本项目,你需要下载的是COCO数据集对应的版本。

3. 代码解析

现在我们深入了解一下代码的结构及其功能。

导入库

import cv2
import numpy as np

这里导入了OpenCV和NumPy两个库,分别用于图像处理和数学计算。

参数设置

函数detect_live定义了一些参数,允许用户自定义检测行为:

  • camera_index: 指定使用的摄像头索引,默认为0表示默认摄像头。
  • motion_threshold: 设置移动距离阈值,超过该值则认为物体发生了移动。
  • min_confidence: 最小置信度阈值,低于此值的对象不会被考虑。
  • debug: 是否开启调试模式,在屏幕上显示额外的信息。
  • consecutive_motion_frames: 需要连续检测到移动的帧数以确认活体存在。
  • target_class: 目标类别,比如"person"。
def detect_live(
    camera_index=0,
    motion_threshold=10,  # 移动的阈值
    min_confidence=0.5,  # 最小置信度
    debug=False,  # 是否显示调试窗口
    consecutive_motion_frames=5,  # 连续检测到移动的帧数
    target_class="person"  # 目标类别
):

加载YOLOv3模型

接下来加载YOLOv3模型的相关文件,并准备输出层:

    net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")

    with open("coco.names", "r") as f:
        classes = [line.strip() for line in f.readlines()]

    layer_names = net.getLayerNames()
    try:
        output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
    except IndexError:
        output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]

摄像头初始化

打开指定的摄像头并检查是否成功打开:

    cap = cv2.VideoCapture(camera_index)

    if not cap.isOpened():
        print("无法打开摄像头。")
        return

图像处理和目标检测

每帧都经过预处理后送入网络进行预测:

    prev_center = None
    consecutive_motion_count = 0  # 连续检测到移动的帧数计数器
    is_target_detected = False  # 标志变量,用于记录当前帧中是否检测到目标类别

    try:
        while True:
            ret, frame = cap.read()

            if not ret:
                print("无法读取摄像头帧。")
                break

            height, width, _ = frame.shape

            blob = cv2.dnn.blobFromImage(frame, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
            net.setInput(blob)
            outs = net.forward(output_layers)

            class_ids = []
            confidences = []
            boxes = []

            for out in outs:
                for detection in out:
                    scores = detection[5:]
                    class_id = np.argmax(scores)
                    confidence = scores[class_id]
                    if confidence > min_confidence:
                        center_x = int(detection[0] * width)
                        center_y = int(detection[1] * height)
                        w = int(detection[2] * width)
                        h = int(detection[3] * height)
                        x = int(center_x - w / 2)
                        y = int(center_y - h / 2)
                        boxes.append([x, y, w, h])
                        confidences.append(float(confidence))
                        class_ids.append(class_id)
                        if classes[class_id] == target_class:
                            is_target_detected = True  # 检测到目标类别

            indexes = cv2.dnn.NMSBoxes(boxes, confidences, min_confidence, 0.4)

            indexes = np.array(indexes)

            for i in indexes.flatten():
                x, y, w, h = boxes[i]
                label = str(classes[class_ids[i]])
                confidence = confidences[i]

                center = ((x + x + w) // 2, (y + y + h) // 2)

                if prev_center is not None and label == target_class:
                    distance = np.sqrt((center[0] - prev_center[0]) ** 2 + (center[1] - prev_center[1]) ** 2)

                    if distance > motion_threshold:
                        consecutive_motion_count += 1
                    else:
                        consecutive_motion_count = 0

                    if consecutive_motion_count >= consecutive_motion_frames:
                        yield True
                        consecutive_motion_count = 0  # 重置计数器
                else:
                    consecutive_motion_count = 0

                prev_center = center

                if debug:
                    color = (0, 255, 0) if label == target_class else (0, 0, 255)
                    cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)
                    cv2.putText(frame, f"{label}: {confidence:.2f}", (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
                    if label == target_class:
                        cv2.circle(frame, center, 5, (0, 0, 255), -1)

            if not is_target_detected:
                yield False

            is_target_detected = False

            if debug:
                cv2.imshow('Live Detection', frame)

            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

    finally:
        cap.release()
        cv2.destroyAllWindows()

主程序入口

最后,我们通过调用detect_live函数来启动检测过程,并根据返回的结果打印出相应的信息:

if __name__ == "__main__":
    for is_live in detect_live(debug=True):
        if is_live:
            print("Is live: True")
        else:
            print("Is live: False")

4. 运行示例

运行程序时,如果检测到了符合条件的目标并且其移动满足设定的阈值,则会在终端打印出"Is live: True",否则打印"Is live: False"。同时,如果开启了调试模式,还会看到带有标注的视频流。

5. 总结

通过上述步骤,我们建立了一个基于YOLOv3的实时活体检测系统。它能够有效地从视频流中识别特定类别的对象,并根据它们的移动情况来判断是否为活体。这仅仅是利用深度学习技术解决实际问题的一个简单例子;随着技术的发展,未来可能会有更多创新的应用出现。

6. 参考资料

  • YOLO: Real-Time Object Detection
  • OpenCV Documentation

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

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

相关文章

高效特征选择:优化机器学习的嵌入式方法指南

高效特征选择:优化机器学习的嵌入式方法指南 文章目录 一、说明二、特征选择方法三、嵌入式方法四、Lasso正则化五、Python 中的 Lasso 实现六、决策树的特征重要性七、Python 实现八、嵌入式方法和递归特征消除九、结论 一、说明 假设您正在处理一个大型数据集&am…

系统架构:MVVM

引言 MVVM 全称 Model-View-ViewModel,是在 MVP(Model-View-Presenter)架构模式基础上的进一步演进与优化。MVVM 与 MVP 的基本架构相似,但 MVVM 独特地引入了数据双向绑定机制。这一创新机制有效解决了 MVP 模式中 Model 与 Vie…

家校通小程序实战教程04教师管理

目录 1 创建数据源2 搭建管理后台3 搭建查询条件4 功能测试总结 我们上一篇介绍了如何将学生加入班级,学生加入之后就需要教师加入了。教师分为任课老师和班主任,班主任相当于一个班级的管理员,日常可以发布各种任务,发布接龙&…

cesium 3Dtiles变量

原本有一个变亮的属性luminanceAtZenith,但是新版本的cesium没有这个属性了。于是 let lightColor 3.0result._customShader new this.ffCesium.Cesium.CustomShader({fragmentShaderText:void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial mate…

SpringBoot小知识(3):热部署知识

一、热部署 热部署是一个非常消耗内存的机制,在实际大型项目开发中几乎用不到,只有小型项目或者分模块或者不停机更新的时候才会用到,仁者见仁智者见智。 1.1 什么是热部署? 热部署是指在不停止应用程序或服务器的情况下&#xf…

vscode切换anaconda虚拟环境解释器不成功

问题: 切换解释器之后运行代码还是使用的原来的解释器 可以看到,我已经切换了“nlp”解释器,我的nltk包只在“nlp”环境下安装了,但是运行代码依然是"torch"解释器,所以找不到“nltk”包。 在网上找了各种…

widows下永久修改python的pip 配置文件

通过cmd永久修改pip 镜像源: 在cmd中输入: pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple会在"C:\Users\Administrator\AppData\Roaming"目录下创建一个pip\pip.ini文件: 使用记事本打开pip.ini文件…

openssl使用哈希算法生成随机密钥

文章目录 一、openssl中随机数函数**OpenSSL 随机数函数概览**1. **核心随机数函数** **常用函数详解**1. RAND_bytes2. RAND_priv_bytes3. RAND_seed 和 RAND_add4. RAND_status **随机数生成器的熵池****常见用例****注意事项** 二、使用哈希算法生成随机的密钥 一、openssl中…

【Python网络爬虫笔记】6- 网络爬虫中的Requests库

一、概述 Requests 是一个用 Python 语言编写的、简洁且功能强大的 HTTP 库。它允许开发者方便地发送各种 HTTP 请求,如 GET、POST、PUT、DELETE 等,并且可以轻松地处理请求的响应。这个库在 Python 生态系统中被广泛使用,无论是简单的网页数…

pytest+allure生成报告显示loading和404

pytestallure执行测试脚本后,通常会在电脑的磁盘上建立一个临时文件夹,里面存放allure测试报告,但是这个测试报告index.html文件单独去打开,却显示loading和404, 这个时候就要用一些办法来解决这个报告显示的问题了。 用命令产生…

NGO-CNN-BiGRU-Attention北方苍鹰算法优化卷积双向门控循环单元时间序列预测,含优化前后对比

NGO-CNN-BiGRU-Attention北方苍鹰算法优化卷积双向门控循环单元时间序列预测,含优化前后对比 目录 NGO-CNN-BiGRU-Attention北方苍鹰算法优化卷积双向门控循环单元时间序列预测,含优化前后对比预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介…

【S500无人机】--地面端下载

之前国庆的时候导师批了无人机,我们几个也一起研究了几次,基本把无人机组装方面弄的差不多了,还差个相机搭载,今天我们讲无人机的调试 硬件配置如下 首先是地面端下载,大家可以选择下载: Mission Planne地…

CSAPP Cache Lab(缓存模拟器)

前言 理解高速缓存对 C 程序性能的影响,通过两部分实验达成:编写高速缓存模拟器;优化矩阵转置函数以减少高速缓存未命中次数。Part A一开始根本不知道要做什么,慢慢看官方文档,以及一些博客,和B站视频&…

Linux内核4.14版本——ccf时钟子系统(3)——ccf一些核心结构体

目录 1. struct clk_hw 2. struct clk_ops 3. struct clk_core 4. struct clk_notifier 5. struct clk 6. struct clk_gate 7. struct clk_divider 8. struct clk_mux 9. struct clk_fixed_factor 10. struct clk_fractional_divider 11. struct clk_multiplier 12…

点云处理中obb算法原理和法向量求解方法

主要数学原理PCA PCA(Principal Component Analysis,主成分分析)是数据分析中的一种重要技术,通过它可以将高维数据投影到低维空间,找到数据的主要结构。在点云分析中,PCA 可以帮助我们提取点云数据中的主…

shell编程7,bash解释器的 for循环+while循环

声明! 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&#…

【人工智能】Python常用库-TensorFlow常用方法教程

TensorFlow 是一个广泛应用的开源深度学习框架,支持多种机器学习任务,如深度学习、神经网络、强化学习等。以下是 TensorFlow 的详细教程,涵盖基础使用方法和示例代码。 1. 安装与导入 安装 TensorFlow: pip install tensorflow…

wxFormBuilder:可视化设计、学习wxWidgets自带UI控件的好工具

wxFormBuilder很快就能拼出一个界面,而且可以直接出对应的代码,拷贝到项目里小改一下就能用。

Vim操作

1. Vim的模式 2.正常模式->编辑模式 在上⽅插⼊⼀⾏: O在下⽅插⼊⼀⾏: o (open)在当前光标前插⼊: i在⾏⾸插⼊: I在当前光标后插⼊: a在⾏尾插⼊: A 3.常见命令行 1、拷贝当前行 yy ,拷贝当前行向下…

阿里云服务器(centos7.6)部署前后端分离项目(MAC环境)

Jdk17安装部署 下载地址:https://www.oracle.com/java/technologies/downloads/ 选择自己需要的jdk版本进行下载。 通过mac终端scp命令上传下载好的jdk17到服务器的/usr/local目录下 scp -r Downloads/jdk-17.0.13_linux-x64_bin.tar.gz 用户名服务器ip地址:/us…