Python----目标检测(使用YOLO 模型进行线程安全推理和流媒体源)

article/2025/7/13 0:17:34

一、线程安全推理

        在多线程环境中运行YOLO 模型需要仔细考虑,以确保线程安全。Python's threading 模块允许您同时运行多个线程,但在这些线程中使用YOLO 模型时,需要注意一些重要的安全问题。本页将指导您创建线程安全的YOLO 模型推理。

1.1、了解Python 线程

        Python 线程是一种并行形式,允许程序同时运行多个操作。不过,Python 的全局解释器锁(GIL)意味着一次只能有一个线程执行Python 字节码。

        虽然这听起来像是一种限制,但线程仍然可以提供并发性,尤其是在 I/O 绑定操作或使用释放 GIL 的操作(如由YOLO 的底层 C 库执行的操作)时。

1.2、共享模型实例的危险

        在线程外实例化YOLO 模型并在多个线程间共享该实例可能会导致竞赛条件,即由于并发访问,模型的内部状态会被不一致地修改。如果模型或其组件所持有的状态在设计上不是线程安全的,那么问题就会特别严重。

非线程安全示例:单个模型实例

#   Unsafe: Sharing a single model instance across threads  #
from threading import Thread  # 导入线程模块
from ultralytics import YOLO  # 导入YOLO类#   Instantiate the model outside the thread  #
shared_model = YOLO("yolov8n.pt")  # 在线程外实例化YOLO模型。这是不安全的做法!def predict(image_path):"""Predicts objects in an image using a preloaded YOLO model,take path string to image as argument.使用预加载的YOLO模型预测图像中的对象,并将图像路径字符串作为参数。"""results = shared_model.predict(image_path)  # 多个线程共享同一个模型实例进行预测,可能导致线程冲突#   Process results  ##   处理结果(例如,保存、显示等),这里省略具体代码   ##   Starting threads that share the same model instance  #
#   创建并启动多个线程,这些线程共享同一个模型实例   #
Thread(target=predict, args=("image1.jpg",)).start()
Thread(target=predict, args=("image2.jpg",)).start()#   这段代码的问题在于,多个线程同时使用`shared_model`这个模型实例,
#   由于YOLO模型内部的操作可能不是线程安全的,这会导致:
#   -   竞态条件(Race Conditions):多个线程不确定性地访问和修改模型的内部状态,导致结果不可预测。
#   -   数据损坏(Data Corruption):模型的权重或其他内部数据可能被破坏。
#   -   程序崩溃(Crashes):在某些情况下,可能会导致程序崩溃。
#   因此,**绝对不要**在多个线程之间共享同一个YOLO模型实例。

        在上面的例子中 shared_model 被多个线程使用,这可能导致不可预测的结果,因为 predict 可由多个线程同时执行。

非线程安全示例:多个模型实例

#   Unsafe: Sharing multiple model instances across threads can still lead to issues  #
#   不安全:即使使用多个模型实例,在线程间共享仍然可能导致问题   #
from threading import Thread  # 导入线程模块
from ultralytics import YOLO  # 导入YOLO类#   Instantiate multiple models outside the thread  #
#   在线程外实例化多个模型   #
shared_model_1 = YOLO("yolov8n_1.pt")  # 创建第一个YOLO模型实例
shared_model_2 = YOLO("yolov8n_2.pt")  # 创建第二个YOLO模型实例def predict(model, image_path):"""Runs prediction on an image using a specified YOLO model, returning the results.使用指定的YOLO模型对图像进行预测,并返回结果。"""results = model.predict(image_path)  # 使用传入的模型进行预测#   Process results  ##   处理结果(例如,保存、显示等),这里省略具体代码   ##   Starting threads with individual model instances  #
#   创建并启动线程,每个线程使用不同的模型实例   #
Thread(target=predict, args=(shared_model_1, "image1.jpg")
).start()  # 创建并启动第一个线程,使用shared_model_1
Thread(target=predict, args=(shared_model_2, "image2.jpg")
).start()  # 创建并启动第二个线程,使用shared_model_2#   虽然这里每个线程都有自己的模型实例(shared_model_1, shared_model_2),
#   但仍然可能存在线程安全问题。原因在于:
#   1.  **底层资源共享**:YOLO模型可能依赖于一些底层的、非线程安全的库或资源。
#       即使模型实例不同,如果它们共享这些底层资源,仍然可能发生冲突。
#   2.  **全局状态**:某些库或系统可能有全局状态,这些状态可能被YOLO模型修改,
#       从而影响其他线程。
#   3.  **硬件限制**:例如,GPU资源是有限的。如果多个线程同时进行大量的GPU计算,
#       可能会导致性能下降或不稳定的行为。
#
#   因此,为了确保真正的线程安全,**最佳实践是在每个线程内部创建并销毁YOLO模型实例**,
#   而不是在线程外部创建然后分发给线程。

1.3、 线程安全推理

        要执行线程安全推理,应在每个线程中实例化一个单独的YOLO 模型。这样可以确保每个线程都有自己独立的模型实例,从而消除出现竞赛条件的风险。

线程安全示例

# Safe: Instantiating a single model inside each thread
from threading import Thread  # 导入线程模块
from ultralytics import YOLO  # 导入YOLO类def thread_safe_predict(image_path):"""Predict on an image using a new YOLO model instance in a thread-safe manner; takes image path as input.在一个线程安全的方式下,使用一个新的YOLO模型实例对图像进行预测;接受图像路径作为输入。"""local_model = YOLO("yolov8n.pt")  # 在每个线程内部实例化一个新的YOLO模型。这是线程安全的首选方法。results = local_model.predict(image_path)  # 使用当前线程的模型实例进行预测# Process results# 处理结果(例如,保存、显示等),这里省略具体代码# Starting threads that each have their own model instance
# 创建并启动多个线程,每个线程都拥有自己的模型实例
Thread(target=thread_safe_predict, args=("image1.jpg",)).start()
Thread(target=thread_safe_predict, args=("image2.jpg",)).start()# 这种方式是线程安全的,因为每个线程都创建并使用自己独立的YOLO模型实例。
# 这避免了多个线程同时访问和修改同一个模型,从而消除了潜在的竞态条件和数据损坏。
# 每个线程在执行完毕后,其模型实例也会被销毁,不会影响其他线程。

1.4、使用 ThreadingLocked 装饰器

        Ultralytics 提供了 ThreadingLocked 装饰器,可用于确保函数的线程安全执行。该装饰器使用锁来确保一次只能有一个线程执行被装饰的函数。

from ultralytics import YOLO  # 导入YOLO类
from ultralytics.utils import ThreadingLocked  # 导入ThreadingLocked装饰器#   Create a model instance  #
model = YOLO("yolov8n.pt")  # 创建一个YOLO模型实例#   Decorate the predict method to make it thread-safe  #
#   使用 @ThreadingLocked 装饰器使 predict 方法线程安全   #
@ThreadingLocked()
def thread_safe_predict(image_path):"""Thread-safe prediction using a shared model instance.使用共享模型实例进行线程安全预测。"""results = model.predict(image_path)  # 使用共享的模型进行预测return results  # 返回预测结果#   Now you can safely call this function from multiple threads  #
#   现在可以安全地从多个线程调用这个函数了   ##   这段代码使用了 `ThreadingLocked` 装饰器来确保对 `model.predict` 方法的线程安全访问。
#   `ThreadingLocked` 装饰器会在方法调用前后自动加锁和解锁,
#   从而避免了多个线程同时调用 `model.predict` 导致的竞态条件。
#   **需要注意的是**,虽然这种方法可以实现线程安全,但仍然建议在每个线程内部创建自己的模型实例,
#   因为这样可以提供更好的隔离性和避免潜在的资源竞争。

        "(《世界人权宣言》) ThreadingLocked 装饰器在需要跨线程共享模型实例,但又想确保每次只有一个线程可以访问它时特别有用。与为每个线程创建一个新的模型实例相比,这种方法可以节省内存,但可能会降低并发性,因为线程需要等待锁被释放。

1.5、结论

        当使用YOLO 型号与Python'时 threading为了确保线程安全,我们总是在使用模型的线程中实例化模型。这种做法可以避免竞赛条件,确保推理任务可靠运行。

        对于更高级的应用场景和进一步优化多线程推理性能,可以考虑使用基于进程的多进程并行或利用带有专用工作进程的任务队列。

        在多线程Python 环境中使用Ultralytics YOLO 模型时,为防止出现竞赛条件,应在每个线程中实例化一个单独的YOLO 模型。这样可以确保每个线程都有自己独立的模型实例,避免并发修改模型状态。

from threading import Thread  # 导入线程模块 [cite: 53, 54]from ultralytics import YOLO  # 导入YOLO类 [cite: 53, 54]def thread_safe_predict(image_path):"""Predict on an image in a thread-safe manner."""local_model = YOLO("yolov8n.pt")  # 在每个线程中创建一个新的YOLO模型实例 [cite: 53, 54]results = local_model.predict(image_path)  # 使用线程内的模型实例进行预测 [cite: 53, 54]#  Process results  ##  处理预测结果(例如,保存或显示),这里省略具体代码  ##  Starting threads that each have their own model instance  #
#  创建并启动两个线程,每个线程都有自己的YOLO模型实例  #
Thread(target=thread_safe_predict, args=("image1.jpg",)).start()
Thread(target=thread_safe_predict, args=("image2.jpg",)).start()#  这段代码展示了线程安全地使用YOLO进行预测的方法。
#  关键在于,每个线程内部都会创建一个独立的YOLO模型实例,
#  从而避免了多个线程同时访问和修改同一个模型实例可能导致的问题。

二、流媒体源:for-循环

import cv2
from ultralytics import YOLO
#加载YOLOV8模型
model=YOLO("yolov8n.pt")
# 打开视频文件
video_path = 'WH038.mp4'
# cap = cv2.VideoCapture(0)#调用摄像头
cap = cv2.VideoCapture(video_path)
# 遍历视频帧
while cap.isOpened():# 从视频中读取一帧success, frame= cap.read()if success:# 在帧上运行YOLOV8推理results = model(frame)# 在帧上可视化推理结果annotated_frame = results[0].plot()# 显示标注后的帧cv2.imshow("YOLOV8推理结果", annotated_frame)# 如果按下'q'键则退出循环if cv2.waitKey(1) & 0xFF == ord("q"):breakelse:# 如果视频播放完毕,则退出循环break
# 释放视频捕获对象并关闭显示窗口
cap.release()
cv2.destroyWindow()

http://www.hkcw.cn/article/UimuZvkBLy.shtml

相关文章

机器学习知识图谱——朴素贝叶斯算法

目录 一、图解朴素贝叶斯算法知识图谱 二、基本概念 三、核心思想 四、为什么叫“朴素”? 五、算法流程图 六、常见模型类型 七、优点 与 缺点 八、实战代码 (以文本分类为例) 九、应用举例 机器学习知识图谱——朴素贝叶斯算法 一、图解朴素贝叶斯算法知识图谱 该…

ollama+open-webui,本地部署自己的大模型

目录 一、效果预览 二、部署ollama 1.ollama说明 2.安装流程 2.1 windows系统 2.1.1下载安装包 2.1.2验证安装结果 2.1.3设置模型文件保存地址 2.1.4拉取大模型镜像 2.2linux系统 2.2.1下载并安装ollama 2.2.2设置环境变量 2.2.3拉取模型文件 三、部署open-webui…

大模型赋能:2D 写实数字人开启实时交互新时代

在数字化浪潮席卷全球的当下,人工智能技术不断突破创新,其中大模型驱动的 2D 写实数字人正成为实时交互领域的一颗新星,引领着行业变革,为人们带来前所未有的交互体验。 一、2D 写实数字人概述 2D 写实数字人是通过计算机图形学…

效率工具- git rebase 全解

一、前言 对于git rebase 一直不太了解,这几天想着提高下git提交质量,就发现了这个好用的指令,顺便记录一下,好加深记忆 贴出官方文档以便大家进一步学习 Git 二、rebase是作用 rebase 官方解释为变基,可以理解为移动你的分支根节点,维护一个更好的提交记录。rebase把你当前…

【开源】Python打造高效剪贴板历史管理器:实现跨平台生产力工具

📋【开源】Python打造高效剪贴板历史管理器:实现跨平台生产力工具 🌈 个人主页:创客白泽 - CSDN博客 🔥 系列专栏:🐍《Python开源项目实战》 💡 热爱不止于代码,热情源自…

π0的微调——如何基于各种开源数据集、以及私有数据集微调openpi(含我司七月的微调实践及在机械臂上的部署)

前言 25年2.4日,几个月前推出π0的公司Physical Intelligence (π)宣布正式开源π0及π0-FAST,如之前所介绍的,他们对用超过 10,000 小时的机器人数据进行了预训练 该GitHub代码仓库「 π0及π0-FAST的GitHub地址:github.com/Ph…

开源模型应用落地-qwen模型小试-Qwen3-8B-融合VLLM、MCP与Agent(七)

一、前言 随着Qwen3的开源与技术升级,其在企业中的落地场景正加速拓展至多个垂直领域。依托Agent智能体能力 和MCP协议的工具调用接口 ,Qwen3可深度融入企业业务流程,为企业提供从需求解析到自动化开发的全链路支持。 本篇将介绍如何实现Qwen3-8B模型集成MCP实现智能体交互。…

【Git】GitHub 连接失败解决方案:Failed to connect to github.com port 443 after 21090 ms: Couldn’t connect to se

文章目录 一、使用 VPN 环境下的解决方案1. 检查当前代理设置2. 配置 Git 使用代理3. 验证代理设置是否生效4. 刷新 DNS 缓存5. 重新尝试 Git 操作 二、未使用 VPN 环境下的解决方案1. 取消 Git 配置的代理2. 验证代理设置已成功移除3. 重试 Git 操作 三、总结使用 VPN 的解决方…

Java 大视界 -- Java 大数据机器学习模型在元宇宙虚拟场景智能交互中的关键技术(239)

💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…

Digital Reengineering and Localized Implementation of the Five-Dimensional Management Cycle System

A Paradigm Shift in Intelligent Hospital Governance(Preliminary draft of the first-line cooperation project) Abstract This study pioneers a transformative approach to healthcare management through the “Technology-Management-Value” (TMV) triad model, r…

Qwen3:重磅开源,重夺开源第一!(包含详细使用教程)

1.简介 Qwen3,这是 Qwen 系列大型语言模型的最新成员。我们的旗舰模型 Qwen3-235B-A22B 在代码、数学、通用能力等基准测试中,与 DeepSeek-R1、o1、o3-mini、Grok-3 和 Gemini-2.5-Pro 等顶级模型相比,表现出极具竞争力的结果。此外&#xf…

基于 Alpine 定制单功能用途(kiosk)电脑

前言 故事回到 7 年前, 在网上冲浪的时候发现了一篇介绍使用 Ubuntu 打造 kiosk 单功能用途电脑的文章, 挺好玩的, 就翻译了一下并比葫芦画瓢先后用了 CentOS 7, ArchLinux 进行了实现. 历史文章: 翻译 - 使用Ubutnu14.04和Chrome打造单功能用途电脑(大屏展示电脑) 使用CentOS…

《汇编语言》第13章 int指令——实验13 编写、应用中断例程

(1)编写并安装 int 7ch 中断例程,功能为显示一个用0结束的字符串,中断例程安装在0:200处。 参数:(dh)行号,(dl)列号,(cl&a…

大模型前处理-CPU

前处理包含哪些流程 分词 tokenizationembedding CPU可以做哪些优化 分词 分词在做什么? 什么是词元化? 词元化(Tokenization)是把一段自然语言文本拆分成更小的单元(称为“词元”,即 Token&#xff0…

设备驱动与文件系统:02 键盘

操作系统中键盘驱动的讲解 在这一讲中,我将为大家讲解键盘相关内容。从上一讲开始,我们进入了操作系统第四个部分的学习,也就是操作系统对设备的驱动与管理。 上一讲我们探讨的是显示器,并且提到,一个终端设备是由显示…

工作流引擎-18-开源审批流项目之 plumdo-work 工作流,表单,报表结合的多模块系统

工作流引擎系列 工作流引擎-00-流程引擎概览 工作流引擎-01-Activiti 是领先的轻量级、以 Java 为中心的开源 BPMN 引擎,支持现实世界的流程自动化需求 工作流引擎-02-BPM OA ERP 区别和联系 工作流引擎-03-聊一聊流程引擎 工作流引擎-04-流程引擎 activiti 优…

Windows环境下Scoop包管理工具的全面指南

🧩 一、Scoop核心特性与设计理念 定位与优势 专注于开源命令行工具和便携式(Portable)应用,无需管理员权限即可安装,减少系统污染。自动管理环境变量(通过shims目录),安装后即时可用…

谷粒商城-分布式微服务项目-高级篇[三]

十五、商城业务-支付 15.1 支付宝支付 15.1.1 进入“蚂蚁金服开放平台” 支付宝开放 平台地址: 支付宝开放平台 15.1.2 下载支付宝官方 demo,进行配置和测试 开发者文档:支付宝开放平台文档中心 电脑网站支付文档:小程序文…

EchoMimicV2:迈向引人注目、简化的半身人类动画

今天介绍EchoMimicV2,EchoMimicV2是阿里蚂蚁集团推出的半身人体AI数字人项目,输入参考图片、音频、和手部姿势序列生成动画视频(对图片的规范要求比较高,图片规范的话效果还可以),感兴趣的还可以去了解一下…

SpringBoot手动实现流式输出方案整理以及SSE规范输出详解

背景: 最近做流式输出时,一直使用python实现的,应需求方的要求,需要通过java应用做一次封装并在java侧完成系统鉴权、模型鉴权等功能后才能真正去调用智能体应用,基于此调研java实现流式输出的几种方式,并…