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

news2025/7/23 5:57:27

一、线程安全推理

        在多线程环境中运行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"):
            break
    else:
        # 如果视频播放完毕,则退出循环
        break
# 释放视频捕获对象并关闭显示窗口
cap.release()
cv2.destroyWindow()

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

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

相关文章

jvm学习第1day jvm简介,栈溢出、堆溢出

jvm学习第1day jvm简介,栈溢出、堆溢出 jvm简介栈线程安全栈溢出线程运行诊断堆堆溢出 方法区方法区内存溢出常量池和运行时常量池 jvm简介 jvm 是编译后的字节码文件运行的环境, 因此各个平台有了jvm可以运行java.class文件,这是Java跨平台…

用广告维持的免费 AI 图像生成工具(个人项目分享)

用广告维持的免费 AI 图像生成工具(个人项目分享) 免费 AI 图像生成工具网址:https://aiart.gcc.ac.cn/ 最近做了一个 AI 图像生成器,主要目标是“尽量简单”: 打开网页就能用不用注册、不用登录免费,不…

分析Web3下数据保护的创新模式

在这个信息爆炸的时代,我们正站在 Web3 的门槛上,迎接一个以去中心化、用户主权和数据隐私为核心的新时代。Web3 不仅仅是技术的迭代,它更是一场关于数据权利和责任的结构性变革。本文将探讨 Web3 下数据保护的创新模式,以期为用户…

​减少交通拥堵、提高效率、改善交通安全的智慧交通开源了。

智慧交通视觉监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。用户只需在界面上…

协议融合驱动效能跃升:Modbus转Ethernet IP的挤出吹塑机应用

在现代工业自动化领域,Modbus作为一种串行通信协议,其稳定性和简单性被广泛应用于各种工控设备中。但随着技术的进步,对于更高速、更远传输距离的需求日益增长,这就需要将Modbus协议通过以太网进行传输,即实现Modbus T…

bug 记录 - 使用 el-dialog 的 before-close 的坑

需求说明 弹窗中内嵌一个 form 表单 原始代码 <script setup lang"ts"> import { reactive, ref } from "vue" import type { FormRules } from element-plus const ruleFormRef ref() interface RuleForm {name: stringregion: number | null } …

Next.js 中间件鉴权绕过漏洞 CVE-2025-29927

前言:CVE-2025-29927 是一个影响 Next.js 的严重漏洞&#xff0c;源于开发者信任了客户端请求中携带的 X-Middleware-Rewrite 头部字段。攻击者可以手动构造该头部&#xff0c;实现绕过中间件逻辑&#xff0c;访问本应受保护的资源或 API。 影响版本&#xff1a;Next.js < …

基于YOLO-NAS-Pose的无人机象群姿态估计:群体行为分析的突破

【导读】 应对气候变化对非洲象的生存威胁&#xff0c;本研究创新采用无人机航拍结合AI姿态分析技术&#xff0c;突破传统观测局限。团队在肯尼亚桑布鲁保护区对比测试DeepLabCut与YOLO-NAS-Pose两种模型&#xff0c;首次将后者引入野生动物研究。通过检测象群头部、脊柱等关键…

8天Python从入门到精通【itheima】-71~72(数据容器“序列”+案例练习)

目录 71节-数据容器“序列”的切片 1.学习目标 2.什么是序列 3.序列的常用操作——切片 4.小节总结 72节——案例练习&#xff1a;序列的切片实践 1.案例需求 2.代码实战 好了&#xff0c;又一篇博客和代码写完了&#xff0c;励志一下吧&#xff0c;下一小节等等继续&a…

dvwa10——XSS(DOM)

XSS攻击&#xff1a; DOM型XSS 只在浏览器前端攻击触发&#xff1a;修改url片段代码不存储 反射型XSS 经过服务器攻击触发&#xff1a;可能通过提交恶意表单&#xff0c;连接触发代码不存储 存储型XSS 经由服务器攻击触发&#xff1a;可能通过提交恶意表单&#xff0c;连…

dvwa14——JavaScript

LOW 先按提示尝试输入success&#xff0c;提交失败 那用bp抓包一下 &#xff0c;抓到这些&#xff0c;发现有token验证&#xff0c;说明改对token才能过 返回页面f12看一下源码&#xff0c;发现value后面的值像密码&#xff0c;于是试一下md5和rot13的解密 ROT13加密/解密 - …

机器学习实验八--基于pca的人脸识别

基于pca的人脸识别 引言&#xff1a;pca1.pca是什么2.PCA算法的基本步骤 实例&#xff1a;人脸识别1.实验目的2.实现步骤3.代码实现4.实验结果5.实验总结 引言&#xff1a;pca 1.pca是什么 pca是一种统计方法&#xff0c;它可以通过正交变换将一组可能相关的变量转换成一组线…

LabVIEW的AMC架构解析

此LabVIEW 程序基于消息队列&#xff08;Message Queue&#xff09;机制构建 AMC 架构&#xff0c;核心包含消息生成&#xff08;MessageGenerator &#xff09;与消息处理&#xff08;Message Processor &#xff09;两大循环&#xff0c;通过队列传递事件与指令&#xff0c;实…

MySQL 索引:为使用 B+树作为索引数据结构,而非 B树、哈希表或二叉树?

在数据库的世界里&#xff0c;性能是永恒的追求。而索引&#xff0c;作为提升查询速度的利器&#xff0c;其底层数据结构的选择至关重要。如果你深入了解过 MySQL&#xff08;尤其是其主流存储引擎 InnoDB&#xff09;&#xff0c;你会发现它不约而同地选择了 B树 作为索引的主…

ubuntu屏幕复制

在ubnuntu20中没有办法正常使用镜像功能,这里提供一下复制屏幕的操作. 使用xrandr查看所有的显示器情况 这里我发现自己的电脑没有办法直接设置分辨率,但是外接的显示器可以设置,从命令行来说就是设置: xrandr --output HDMI-0 --mode 1920x1080那怎么样才能将原生电脑屏幕换…

Spring WebFlux 整合AI大模型实现流式输出

前言 最近赶上AI的热潮&#xff0c;很多业务都在接入AI大模型相关的接口去方便的实现一些功能&#xff0c;后端需要做的是接入AI模型接口&#xff0c;并整合成流式输出到前端&#xff0c;下面有一些经验和踩过的坑。 集成 Spring WebFlux是全新的Reactive Web技术栈&#xf…

验证电机理论与性能:电机试验平板提升测试效率

电机试验平板提升测试效率是验证电机理论与性能的重要环节之一。通过在平板上进行电机试验&#xff0c;可以对电机的性能参数进行准确测量和分析&#xff0c;从而验证电机的理论设计是否符合实际表现。同时&#xff0c;提升测试效率可以加快试验过程&#xff0c;节约时间和成本…

Simplicity studio SDK下载和安装,创建工程

下载SDK工具地址 Simplicity Studio - Silicon Labs 选择适合自己电脑的版本。 这个就使用你自己的邮箱注册一个就可以了&#xff0c;我是用的公司邮箱注册的。 下载完成&#xff1a; 安装 下载完成后右键点击安装&#xff0c;一路下一步 安装完成后&#xff0c;程序自动打…

OpenCV——Mac系统搭建OpenCV的Java环境

这里写目录标题 一、源码编译安装1.1、下载源码包1.2、cmake安装1.3、java配置1.4、测试 二、Maven引入2.1、添加Maven依赖2.2、加载本地库 一、源码编译安装 1.1、下载源码包 官网下载opencv包&#xff1a;https://opencv.org/releases/ 以4.6.0为例&#xff0c;下载解压后&…

【设计模式-3.4】结构型——代理模式

说明&#xff1a;说明&#xff1a;本文介绍结构型设计模式之一的代理模式 定义 代理模式&#xff08;Proxy Pattern&#xff09;指为其他对象提供一种代理&#xff0c;以控制对这个对象的访问&#xff0c;属于结构型设计模式。&#xff08;引自《设计模式就该这样学》P158&am…