当前位置: 首页 > news >正文

使用OpenCV和卡尔曼滤波器进行实时活体检测

引言

在现代计算机视觉应用中,实时检测和跟踪物体是一项重要的任务。本文将详细介绍如何使用OpenCV库和卡尔曼滤波器来实现一个实时的活体检测系统。该系统能够通过摄像头捕捉视频流,并使用YOLOv3模型来检测目标对象(例如人),同时利用卡尔曼滤波器来预测目标的运动轨迹。本文将逐步介绍代码的实现过程,并解释每个部分的功能。

1. 环境准备

在开始编写代码之前,确保已经安装了以下依赖库:

  • OpenCV
  • NumPy
  • FilterPy

可以使用pip命令来安装这些库:

pip install opencv-python numpy filterpy

2. 代码结构

2.1 导入必要的库

import cv2
import numpy as np
from filterpy.kalman import KalmanFilter
from filterpy.common import Q_discrete_white_noise

2.2 初始化卡尔曼滤波器

卡尔曼滤波器是一种用于估计线性动态系统的状态的算法。在这里,我们使用它来预测目标的位置和速度。

def init_kalman_filter():kf = KalmanFilter(dim_x=4, dim_z=2)kf.x = np.zeros((4, 1))  # 初始状态 [x, y, vx, vy]kf.F = np.array([[1, 0, 1, 0],[0, 1, 0, 1],[0, 0, 1, 0],[0, 0, 0, 1]], dtype=float)  # 状态转移矩阵kf.H = np.array([[1, 0, 0, 0],[0, 1, 0, 0]])  # 观测矩阵kf.P *= 1000  # 初始协方差kf.R = np.eye(2) * 5  # 测量噪声kf.Q = Q_discrete_white_noise(dim=4, dt=1, var=0.1)  # 过程噪声return kf

2.3 更新卡尔曼滤波器

每次获取新的观测值时,我们需要更新卡尔曼滤波器的状态。

def update_kalman_filter(kf, measurement):kf.predict()kf.update(measurement)return kf.x[0, 0], kf.x[1, 0], kf.x[2, 0], kf.x[3, 0]

2.4 实时检测函数

detect_live 函数是整个系统的核心,它负责从摄像头读取视频流,检测目标,并使用卡尔曼滤波器进行预测。

def detect_live(camera_index=0,motion_threshold=10,  # 移动的阈值min_confidence=0.5,  # 最小置信度debug=False,  # 是否显示调试窗口consecutive_motion_frames=5,  # 连续检测到移动的帧数target_class="person"  # 目标类别
):# 加载 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("无法打开摄像头。")returnprev_frame = Noneprev_centers = []  # 用于存储前几帧的目标中心点consecutive_motion_count = 0  # 连续检测到移动的帧数计数器is_target_detected = False  # 标志变量,用于记录当前帧中是否检测到目标类别kf = init_kalman_filter()  # 初始化卡尔曼滤波器try:while True:# 读取摄像头帧ret, frame = cap.read()if not ret:print("无法读取摄像头帧。")breakheight, 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 转换为 NumPy 数组indexes = np.array(indexes)current_centers = []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)current_centers.append(center)if len(prev_centers) > 0 and label == target_class:# 如果有前一帧的数据,计算速度和方向prev_center = prev_centers[-1]distance = np.sqrt((center[0] - prev_center[0]) ** 2 + (center[1] - prev_center[1]) ** 2)speed = distance  # 单位是像素/帧direction = (center[0] - prev_center[0], center[1] - prev_center[1])# 更新卡尔曼滤波器x, y, vx, vy = update_kalman_filter(kf, np.array([center[0], center[1]]))# 简单的行为预测if speed > motion_threshold:consecutive_motion_count += 1else:consecutive_motion_count = 0# 如果连续检测到足够的移动,认为是活体if consecutive_motion_count >= consecutive_motion_frames:yield {"is_live": True, "speed": speed, "direction": direction, "predicted_position": (x, y),"predicted_velocity": (vx, vy)}consecutive_motion_count = 0  # 重置计数器else:consecutive_motion_count = 0# 在调试模式下绘制框if debug:color = (0, 255, 0) if label == target_class else (0, 0, 255)  # 绿色表示目标类别,红色表示其他类别# 确保坐标是整数类型x, y, w, h = int(x), int(y), int(w), int(h)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)cv2.circle(frame, (int(x), int(y)), 5, (0, 255, 0), -1)  # 预测位置# 更新前一帧的中心点列表prev_centers = current_centers# 如果没有检测到目标类别,输出不是活体if not is_target_detected:yield {"is_live": False}# 重置标志变量is_target_detected = False# 显示当前帧(仅在调试模式下)if debug:cv2.imshow('Live Detection', frame)# 按 'q' 键退出循环if cv2.waitKey(1) & 0xFF == ord('q'):breakfinally:# 释放摄像头并关闭所有窗口cap.release()cv2.destroyAllWindows()

2.5 主程序

主程序调用 detect_live 函数,并打印出检测结果。

if __name__ == "__main__":for result in detect_live(debug=True):if result["is_live"]:print(f"Is live: True, Speed: {result['speed']:.2f} pixels/frame, Direction: {result['direction']}, Predicted Position: {result['predicted_position']}, Predicted Velocity: {result['predicted_velocity']}")else:print("Is live: False")

3. 代码详解

3.1 初始化卡尔曼滤波器

卡尔曼滤波器初始化时定义了状态向量、状态转移矩阵、观测矩阵、初始协方差矩阵、测量噪声和过程噪声。这些参数决定了卡尔曼滤波器的性能。

3.2 更新卡尔曼滤波器

每次获取新的观测值时,卡尔曼滤波器会先进行预测,然后根据新的观测值更新状态。这样可以得到更准确的目标位置和速度估计。

3.3 实时检测

detect_live 函数首先加载YOLOv3模型,然后打开摄像头并开始读取视频流。对于每一帧,它都会进行以下操作:

  1. 对图像进行预处理。
  2. 使用YOLOv3模型进行目标检测。
  3. 使用非极大值抑制(NMS)去除重复的检测框。
  4. 计算目标的中心点。
  5. 如果检测到目标,计算目标的速度和方向。
  6. 更新卡尔曼滤波器以预测目标的未来位置。
  7. 在调试模式下绘制检测框和预测位置。
  8. 如果连续多帧检测到目标移动,认为是活体。
  9. 显示当前帧(仅在调试模式下)。

4. 结论

本文详细介绍了如何使用OpenCV和卡尔曼滤波器实现一个实时的活体检测系统。通过结合YOLOv3模型的强大检测能力和卡尔曼滤波器的预测能力,我们可以构建一个高效且准确的实时检测系统。这个系统可以应用于各种场景,如安全监控、自动驾驶等。

相关文章:

使用OpenCV和卡尔曼滤波器进行实时活体检测

引言 在现代计算机视觉应用中,实时检测和跟踪物体是一项重要的任务。本文将详细介绍如何使用OpenCV库和卡尔曼滤波器来实现一个实时的活体检测系统。该系统能够通过摄像头捕捉视频流,并使用YOLOv3模型来检测目标对象(例如人)&…...

【25春招前端八股文】——JS数据类型检测方式

检测数据类型 # typeof 总结:数组、对象、null都会被判断为object,其他判断都正确的类型。 可以检测基本数据类型null会检测为Object,因为null也是一个空的引用对象复杂数据类型只能检测function和Object 情况说明: 数组&#x…...

Kafka的学习路径规划

目录标题 1. 记(记忆力)Kafka核心概念Kafka关键配置 2. 懂(理解力)Kafka工作原理Kafka核心功能Kafka架构设计 3. 网(知识网络)技术栈整合用例和场景 4. 拓(全面拓展)学习材料多样化内…...

linux模拟试题

Linux 基础阶段考试笔试模拟试卷 审核人:王旺旺 一.填空题(每题 1 分,共 30 分) 1.验证 httpd 服务是否启动的命令是_______ 答:systemctl status httpd 或 netstat -anptl 或 ss -anpt 2.将目录 xxhf 下所有文件的所属组改为 user1 的命令是_______ 答:chown -R ,user1 …...

Qt-界面优化QSS

QSS介绍 先说下CSS: 在⽹⻚前端开发领域中, CSS 是⼀个⾄关重要的部分. 描述了⼀个⽹⻚的 "样式". 从⽽起到对⽹⻚美化的作⽤。 Qt 仿照 CSS 的模式, 引⼊了 QSS, 来对 Qt 中的控件做出样式上的设定 。 CSS的功能很强大,QSS要逊色一些&#…...

QT实战-qt各种菜单样式实现

本文主要介绍了qt普通菜单样式、带选中样式、带子菜单样式、超过一屏幕菜单样式、自定义带有滚动条的菜单样式, 先上图如下: 1.普通菜单样式 代码: m_pmenu new QMenu(this);m_pmenu->setObjectName("quoteListMenu"); qss文…...

深度学习基础03_BP算法(下)过拟合和欠拟合

目录 一、BP算法(下) 0、反向传播代码回顾 写法一: 写法二(更常用): 1、BP中的梯度下降 1.数学描述 2.传统下降方式 3.优化梯度下降方式 指数加权平均 Momentum AdaGrad RMSProp Adam(常用) 总结 二、过拟合和欠拟合 1、概念 1.过拟合 …...

web vue 滑动选择 n宫格选中 九宫格选中

页面动态布局经常性要交给客户来操作,他们按时他们的习惯在同一个屏幕内显示若干个子视图,尤其是在医学影像领域对于影像的同屏显示目视对比显的更为重要。 来看看如下的用户体验: 设计为最多支持5行6列页面展示后,右侧的布局则动…...

Spring Boot整合EasyExcel

Spring Boot整合EasyExcel主要涉及到以下几个步骤: 1.添加EasyExcel依赖到Spring Boot项目的pom.xml文件中。 2.创建数据模型类,用于映射Excel文件中的数据。 3.编写读取和写入Excel的服务。 以下是一个简单的例子: 1.添加EasyExcel依赖 …...

微软表示不会使用你的 Word、Excel 数据进行 AI 训练

​微软否认使用 Microsoft 365 应用程序(包括 Word、Excel 和 PowerPoint)收集数据来训练公司人工智能 (AI) 模型的说法。 此前,Tumblr 的一篇博文声称,雷德蒙德使用“互联体验”功能抓取客户的 Word 和 Excel 数据,用…...

JavaScript(一)

1.JavaScript 基本使用 2.JavaScript简单事件 3.JavaScript修改样式 4.JavaScript数据类型 JavaScript和Java有什么关系 知识点一 JavaScript基本使用 JS写在哪 还有一种写在中间的&#xff0c;也就是<head>里面 JS一些注意事项 JS修改元素内容 #JS获取对象<…...

Day 32 动态规划part01

今天正式开始动态规划! 理论基础 无论大家之前对动态规划学到什么程度,一定要先看 我讲的 动态规划理论基础。 如果没做过动态规划的题目,看我讲的理论基础,会有感觉 是不是简单题想复杂了? 其实并没有,我讲的理论基础内容,在动规章节所有题目都有运用,所以很重要!…...

winform跨线程更新界面

前言&#xff1a; 大家好&#xff0c;我是上位机马工&#xff0c;硕士毕业4年年入40万&#xff0c;目前在一家自动化公司担任软件经理&#xff0c;从事C#上位机软件开发8年以上&#xff01;我们在开发C#程序的时候&#xff0c;有时候需要在非Ui主线程更新界面&#xff0c;为了…...

【合作原创】使用Termux搭建可以使用的生产力环境(二)

前言 上期文章没看的可以先从上期文章开始看起 【合作原创】使用Termux搭建可以使用的生产力环境&#xff08;一&#xff09;-CSDN博客 目前我们已经完成了FinalShell ssh连接手机Termux的功能了&#xff0c;这期我们继续朝我们的目标前进。今天早上有读者进群以为生成环境指…...

微积分复习笔记 Calculus Volume 2 - 3.3 Trigonometric Substitution

3.3 Trigonometric Substitution - Calculus Volume 2 | OpenStax...

vue2+svg+elementui实现花瓣图自定义el-select回显色卡图片

项目需要实现花瓣图&#xff0c;但是改图表在echarts&#xff0c;highCharts等案例中均未出现&#xff0c;有类似的韦恩图&#xff0c;但是和需求有所差距&#xff1b; 为实现该效果&#xff0c;静态图表上采取svg来手动绘制花瓣&#xff1a; 确定中心点&#xff0c;以该点为中…...

记录一次网关异常

记一次网关异常 网关时不时就会出现下面的异常。关键是不知道什么时候就会报错&#xff0c;并且有时候就算什么都不操作&#xff0c;也会导致这个异常。 ERROR org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in schedul…...

计算机网络——不同版本的 HTTP 协议

介绍 HTTP&#xff0c;即超文本传输协议&#xff08;HyperText Transfer Protocol&#xff09;&#xff0c;是应用层的一个简单的请求-响应协议&#xff0c;它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。本文将介绍 HTTP 协议各个版本。 HTTP/1.0 HTTP/1…...

使用 LLaMA-Factory 微调

git clone https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory pip install -e . pip install tf-keras[dataset_info.json](dataset_info.json) 包含了所有可用的数据集。如果您希望使用自定义数据集&#xff0c;请**务必**在 dataset_info.json 文件中添加*数据…...

vue2 虚拟DOM 和 真实DOM (概念、作用、Diff 算法)

虚拟 DOM 和 真实DOM&#xff08;概念、作用、Diff 算法&#xff09; 1.1 概念 真实 DOM&#xff08;Document Object Model&#xff09;&#xff1a;是浏览器中用于表示文档结构的树形结构。 <h2>你好</h2>虚拟DOM&#xff1a;用 JavaScript 对象来模拟真实 DOM…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

C++ 设计模式 《小明的奶茶加料风波》

&#x1f468;‍&#x1f393; 模式名称&#xff1a;装饰器模式&#xff08;Decorator Pattern&#xff09; &#x1f466; 小明最近上线了校园奶茶配送功能&#xff0c;业务火爆&#xff0c;大家都在加料&#xff1a; 有的同学要加波霸 &#x1f7e4;&#xff0c;有的要加椰果…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

Monorepo架构: Nx Cloud 扩展能力与缓存加速

借助 Nx Cloud 实现项目协同与加速构建 1 &#xff09; 缓存工作原理分析 在了解了本地缓存和远程缓存之后&#xff0c;我们来探究缓存是如何工作的。以计算文件的哈希串为例&#xff0c;若后续运行任务时文件哈希串未变&#xff0c;系统会直接使用对应的输出和制品文件。 2 …...

aardio 自动识别验证码输入

技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”&#xff0c;于是尝试整合图像识别与网页自动化技术&#xff0c;完成了这套模拟登录流程。核心思路是&#xff1a;截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...

webpack面试题

面试题&#xff1a;webpack介绍和简单使用 一、webpack&#xff08;模块化打包工具&#xff09;1. webpack是把项目当作一个整体&#xff0c;通过给定的一个主文件&#xff0c;webpack将从这个主文件开始找到你项目当中的所有依赖文件&#xff0c;使用loaders来处理它们&#x…...