通过 HTTP 获取远程摄像头视频流并使用 YOLOv5 进行目标检测

news2024/11/15 23:19:55

在本教程中,我们将通过 HTTP 获取远程摄像头视频流,并使用 YOLOv5 模型进行实时目标检测。我们会利用 Python 的 OpenCV 库获取视频流,使用 YOLOv5 模型进行目标检测,并使用多线程来提高实时性和效率。

项目地址:like45599/realtime-object-detection: 通过 HTTP 获取远程摄像头视频流并使用 YOLOv5 进行目标检测

使用 Flask 实现远程摄像头访问的完整流程

1. 项目需求分析
  • 目标:通过 Flask 和 OpenCV,将笔记本的摄像头视频流通过局域网共享,主机可以远程访问并查看实时视频流。

  • 解决方案:使用 Flask 创建 Web 服务,通过 OpenCV 读取摄像头的视频帧,并将其以流的形式传递到客户端,实现远程实时访问。

参考:akmamun/camera-live-streaming: Camera Live Streaming with Flask and Open-CV

2. 环境准备
  • 依赖安装:确保安装了 Flask 和 OpenCV 库。

    pip install flask opencv-python
  • 文件结构

    camera-live-streaming/
    ├── app.py          # Flask 应用主文件
    ├── camera.py       # 摄像头读取类
    └── templates/
        └── index.html  # Web 页面模板
3. 代码实现
3.1 创建 camera.py:实现摄像头读取功能
  • VideoCamera 类使用 OpenCV 读取摄像头数据,并提供帧读取和备用帧方法。

   # camera.py
   import cv2
​
   class VideoCamera(object):
       def __init__(self):
           self.video = cv2.VideoCapture(0)  # 使用默认摄像头
​
       def __del__(self):
           self.video.release()  # 释放摄像头资源
​
       def get_frame(self):
           success, image = self.video.read()  # 读取一帧图像
           if not success:
               raise Exception("Failed to read frame from camera")
           ret, jpeg = cv2.imencode('.jpg', image)  # 编码为 JPEG 格式
           return jpeg.tobytes()
​
       def get_heartbeat(self):
           image = cv2.imread('noise-green.jpg')  # 备用图像
           ret, jpeg = cv2.imencode('.jpg', image)
           return jpeg.tobytes()
3.2 创建 app.py:搭建 Flask 应用
  • 配置 Flask 应用并实现视频流传输。

  • gen() 函数持续获取视频帧并通过 HTTP 响应流形式发送给客户端。

   # app.py
   from camera import VideoCamera
   from flask import Flask, render_template, Response
   import time
​
   app = Flask(__name__)
​
   @app.route('/')
   def index():
       return render_template('index.html')  # 渲染主页模板
​
   def gen(camera):
       while True:
           try:
               frame = camera.get_frame()
           except Exception:
               print("Video is finished or empty")
               frame = camera.get_heartbeat()
           yield (b'--frame\r\n'
                  b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
​
   @app.route('/video_feed')
   def video_feed():
       return Response(gen(VideoCamera()),
                       mimetype='multipart/x-mixed-replace; boundary=frame')
​
   if __name__ == '__main__':
       app.run(host='0.0.0.0', port=5000, threaded=True)
3.3 创建 index.html:构建前端显示页面
  • templates 文件夹中创建 index.html,用于显示实时视频流。

   <!doctype html>
   <html lang="en">
   <head>
       <meta charset="utf-8">
       <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
       <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
       <title>Live Streaming</title>
   </head>
   <body>
       <div class="container">
           <div class="row">
               <div class="col-lg-8 offset-lg-2">
                   <h3 class="mt-5">Live Streaming</h3>
                   <img src="{{ url_for('video_feed') }}" width="100%">
               </div>
           </div>
       </div>
   </body>
   </html>
4. 项目运行

启动 Flask 应用

  • 在项目目录下,直接运行 app.py 文件(不要使用 flask run),确保 Flask 绑定到 0.0.0.0

   python app.py

检查启动日志

  • 确保日志显示 Running on http://0.0.0.0:5000/,表明服务已经绑定到所有网络接口。

5. 测试与访问
  • 在主机上,通过笔记本的 IP 地址访问 Flask 服务。例如,笔记本 IP 是 xxx.xxx.xxx.xxx,可以通过以下地址访问:

    http://xxx.xxx.xxx.xxx:5000/
  • 如果可以正常显示视频流,说明功能实现成功。

6. 注意事项与问题排查
  • 防火墙配置:确保防火墙允许 5000 端口访问。可以通过临时关闭防火墙或为 5000 端口创建入站规则来测试。

  • Flask 绑定设置app.run(host='0.0.0.0', port=5000, threaded=True) 确保 Flask 应用可以被局域网内的其他设备访问。

  • 调试信息:在 index() 函数内打印日志信息,以便确认请求是否正确到达 Flask 服务。

  • 网络连接问题:确保笔记本和主机在同一局域网内,且处于相同的子网中。

  • 替代端口:如有端口冲突或无法访问问题,可以尝试更换端口,比如 5001


这样一来,通过 Flask 和 OpenCV 实现的远程摄像头访问项目就完成了!可以轻松地在局域网内实时查看摄像头视频流,并且该项目可以作为远程监控、流媒体传输等应用的基础架构。

获取远程视频流并进行目标检测项目结构与代码解析

项目目录结构
realtime-object-detection/            # 项目根目录
├── assets/                           # 存放所有模型和相关资源
│   └── yolov5s.pt                    # 保存的 YOLOv5 模型权重
├── config/                           # 存放配置文件
    ├── __init__.py
│   └── config.py                     # 配置文件,存放视频 URL 和模型路径等
├── model/                            # 存放模型加载和推理相关代码
    ├── __init__.py
│   └── yolov5_model.py               # 加载和进行目标检测的代码
├── video/                            # 存放视频流相关功能
    ├── __init__.py
│   └── video_stream.py               # 获取视频流并传递给目标检测模型
├── main.py                           # 主程序,执行目标检测任务
└── requirements.txt                  # 记录项目依赖的库
​
目录和文件说明
  • assets/:用于存放项目中使用的资源文件,主要是 YOLOv5 模型权重文件 yolov5s.pt。我们将权重文件保存在该目录下,以便模型能够加载和进行目标检测。

  • config/:存放配置文件。在 config.py 中,我们定义了视频流的 URL 和模型的存储路径等配置信息,以便于在项目中进行调用和修改。

  • model/:包含了与模型相关的代码,包括模型的加载、目标检测函数等。在 yolov5_model.py 文件中,我们负责加载 YOLOv5 模型和进行目标检测的实现。

  • video/:专门处理视频流相关的代码。video_stream.py 文件中的代码用于从远程服务器获取视频流并将其传递给目标检测函数进行实时处理。

  • main.py:主程序文件,负责组织和调用各模块的代码来实现实时目标检测的功能。

  • requirements.txt:记录项目所需的依赖库,便于环境搭建。


关键代码解析

1. 配置文件 config/config.py

config.py 用于存储项目中的配置信息,包括视频流的 URL 和模型的存储路径。示例代码如下:

# 配置文件,存放 URL 和模型路径等
VIDEO_URL = "http://xxx.xxx.xxx.xxx:5000/video_feed"  # 替换为 Flask 服务器的 URL
MODEL_PATH = './assets/yolov5s.pt'  # 模型文件存放路径
2. 模型加载与目标检测 model/yolov5_model.py

yolov5_model.py 文件中,我们实现了两个主要功能:加载 YOLOv5 模型并进行目标检测。

  • load_model():该函数首先尝试从本地加载模型权重文件,如果文件不存在,则会从 YOLOv5 的官方仓库下载预训练模型,并保存到本地。

  • detect_objects():该函数接收一个视频帧并使用 YOLOv5 模型进行目标检测,返回处理后的图像。

import torch
from config.config import MODEL_PATH

# 加载 YOLOv5 模型
def load_model():
    # 创建 YOLOv5 模型(注意:这里只加载模型架构,权重会在后面加载)
    model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=False)  # 不加载预训练权重

    try:
        # 尝试加载本地模型权重
        model.load_state_dict(torch.load(MODEL_PATH))  # 从 assets 目录加载模型权重
        print(f"Loaded YOLOv5 model from {MODEL_PATH}")
    except FileNotFoundError:
        print(f"Model file not found at {MODEL_PATH}, downloading...")
        # 如果模型权重不存在,从官网加载
        model = torch.hub.load('ultralytics/yolov5', 'yolov5s')  # 加载预训练的 yolov5s 模型
        # 保存模型权重到 assets 目录
        torch.save(model.state_dict(), MODEL_PATH)
        print(f"Model downloaded and saved to {MODEL_PATH}")

    model.eval()  # 设置模型为评估模式
    return model

# 目标检测函数
def detect_objects(model, frame):
    # 将 BGR 图像转换为 RGB
    img = frame[..., ::-1]

    # 使用 YOLOv5 进行目标检测
    results = model(img)

    # 绘制检测结果
    results.render()

    # 获取处理后的图像,使用 results.ims 来代替 results.imgs
    frame = results.ims[0]

    return frame
3. 获取视频流并进行目标检测 video/video_stream.py

该文件负责从远程视频流中获取数据,并将其传递给目标检测函数。示例如下:

import cv2

# 获取远程视频流并进行目标检测
def get_video_stream(url, detect_objects, model):
    # 从远程服务器获取视频流
    cap = cv2.VideoCapture(url)

    while True:
        ret, frame = cap.read()
        if not ret:
            break

        # 对每一帧进行目标检测
        frame = detect_objects(model, frame)

        # 显示检测结果
        cv2.imshow("Detection", frame)

        # 按 'q' 键退出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()
4. 主程序 main.py

main.py 中,我们组织了模型加载和视频流获取的功能:

import torch
from config.config import VIDEO_URL
from model.yolov5_model import load_model, detect_objects
from video.video_stream import get_video_stream

def main():
    # 加载 YOLOv5 模型
    model = load_model()

    # 获取远程视频流并进行目标检测
    get_video_stream(VIDEO_URL, detect_objects, model)

if __name__ == '__main__':
    main()

总结

通过合理的项目结构设计,我们将项目功能模块化,使代码更易于维护和扩展。每个功能模块都在独立的文件中实现,便于调试和修改。在模型加载方面,我们通过本地和网络模型的双重处理机制,确保了程序能够在缺少本地模型文件时自动下载并保存。

希望这个项目结构能够帮助你更好地理解如何组织一个基于 YOLOv5 的目标检测项目,并且能够作为参考用于其他类似的深度学习应用中。

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

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

相关文章

Android Framework AMS(17)APP 异常Crash处理流程解读

该系列文章总纲链接&#xff1a;专题总纲目录 Android Framework 总纲 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节主要解读APP Crash处理。关注思维导图中左上侧部分即可。 本章节主要是对Android的APP Crash处理有一个基本的了解。从进程启动到UncaughtH…

javaWeb小白项目--学生宿舍管理系统

目录 一、检查并关闭占用端口的进程 二、修改 Tomcat 的端口配置 三、重新启动 Tomcat 一、javaw.exe的作用 二、结束javaw.exe任务的影响 三、如何判断是否可以结束 结尾&#xff1a; 这个错误提示表明在本地启动 Tomcat v9.0 服务器时遇到了问题&#xff0c;原因是所需…

深度学习在边缘检测中的应用及代码分析

摘要&#xff1a; 本文深入探讨了深度学习在边缘检测领域的应用。首先介绍了边缘检测的基本概念和传统方法的局限性&#xff0c;然后详细阐述了基于深度学习的边缘检测模型&#xff0c;包括其网络结构、训练方法和优势。文中分析了不同的深度学习架构在边缘检测中的性能表现&am…

SpringBoot(十七)创建多模块Springboot项目

在gitee上查找资料的时候,发现有不少Springboot项目里边都是嵌套了多个Springboot项目的。这个玩意好,在协作开发的时候,将项目分成多个模块,有多个团队协作开发,模块间定义标准化通信接口进行数据交互即可。 这个好这个。我之前创建的博客项目是单模块的SpringBoot项目,…

STM32WB55RG开发(2)----STM32CubeProgrammer烧录

STM32WB55RG开发----2.STM32CubeProgrammer烧录 概述硬件准备视频教学样品申请源码下载参考程序自举模式UART烧录USB烧录 概述 STM32CubeProgrammer (STM32CubeProg) 是一款用于编程STM32产品的全功能多操作系统软件工具。 它提供了一个易用高效的环境&#xff0c;通过调试接口…

使用Java爬虫获取商品订单详情:从API到数据存储

在电子商务日益发展的今天&#xff0c;获取商品订单详情成为了许多开发者和数据分析师的需求。无论是为了分析用户行为&#xff0c;还是为了优化库存管理&#xff0c;订单数据的获取都是至关重要的。本文将详细介绍如何使用Java编写爬虫&#xff0c;通过API获取商品订单详情&am…

高性能分布式缓存Redis-分布式锁与布隆过滤器

一、分布式锁 我们先来看一下本地锁 在并发编程中&#xff0c;我们通过锁&#xff0c;来避免由于竞争而造成的数据不一致问题。通常&#xff0c;我们以 synchronized 、Lock 来使用它&#xff08;单机情况&#xff09; 来看这段代码 Autowired RedisTemplate<String,Str…

SpringSecurity+jwt+captcha登录认证授权总结

SpringSecurityjwtcaptcha登录认证授权总结 版本信息&#xff1a; springboot 3.2.0、springSecurity 6.2.0、mybatis-plus 3.5.5 认证授权思路和流程&#xff1a; 未携带token&#xff0c;访问登录接口&#xff1a; 1、用户登录携带账号密码 2、请求到达自定义Filter&am…

从社交媒体到元宇宙:Facebook未来发展新方向

Facebook&#xff0c;作为全球最大的社交媒体平台之一&#xff0c;已经从最初的简单互动工具发展成为一个跨越多个领域的科技巨头。无论是连接人与人之间的社交纽带&#xff0c;还是利用大数据、人工智能等技术为用户提供个性化的体验&#xff0c;Facebook一直引领着社交网络的…

javascript用来干嘛的?赋予网站灵魂的语言

javascript用来干嘛的&#xff1f;赋予网站灵魂的语言 在互联网世界中&#xff0c;你所浏览的每一个网页&#xff0c;背后都有一群默默工作的代码在支撑着。而其中&#xff0c;JavaScript就像是一位技艺精湛的魔术师&#xff0c;它赋予了网页生命力&#xff0c;让原本静态的页…

Wordpress常用配置,包括看板娘跨域等

一个Wordpress的博客已经搭建完成了&#xff0c;那么为了让它看起来更有人间烟火气一点&#xff0c;有一些常用的初始配置&#xff0c;这里整理一下。 修改页脚 页脚这里默认会显示Powered by Wordpress&#xff0c;还有一个原因是这里要加上备案信息。在主题里找到页脚&…

The Internals of PostgreSQL 翻译版 持续更新...

为了方便自己快速学习&#xff0c;整理了翻译版本&#xff0c;目前翻译的还不完善&#xff0c;后续会边学习边完善。 文档用于自己快速参考&#xff0c;会持续修正&#xff0c;能力有限,无法确保正确!!! 《The Internals of PostgreSQL 》 不是 《 PostgreSQL14 Internals 》…

FlinkPipelineComposer 详解

FlinkPipelineComposer 详解 原文 背景 在flink-cdc 3.0中引入了pipeline机制&#xff0c;提供了除Datastream api/flink sql以外的一种方式定义flink 任务 通过提供一个yaml文件&#xff0c;描述source sink transform等主要信息 由FlinkPipelineComposer解析&#xff0c…

MybatisPlus知识

mybatis与mybatisplus的区别&#xff1a; mybatisplus顾名思义时mybatis的升级版&#xff0c;提供了更多的API和方法&#xff0c;是基于mybatis框架基础上的升级&#xff0c;更加方便开发。mybatisplus继承BaseMapper接口并调用其中提供的方法来操作数据库&#xff0c;不需要再…

利用飞书多维表格自动发布版本

文章目录 背景尝试1&#xff0c;轮询尝试2&#xff0c;长连接 背景 博主所在的部门比较奇特&#xff0c;每个车型每周都需要发版&#xff0c;所以实际上一周会发布好几个版本。经过之前使用流水线自动发版改造之后&#xff0c;发版的成本已经大大降低了&#xff0c;具体参考&a…

Qwen2-VL:发票数据提取、视频聊天和使用 PDF 的多模态 RAG 的实践指南

概述 随着人工智能技术的迅猛发展&#xff0c;多模态模型在各类应用场景中展现出强大的潜力和广泛的适用性。Qwen2-VL 作为最新一代的多模态大模型&#xff0c;融合了视觉与语言处理能力&#xff0c;旨在提升复杂任务的执行效率和准确性。本指南聚焦于 Qwen2-VL 在三个关键领域…

蓝桥杯每日真题 - 第7天

题目&#xff1a;&#xff08;爬山&#xff09; 题目描述&#xff08;X届 C&C B组X题&#xff09; 解题思路&#xff1a; 前缀和构造&#xff1a;为了高效地计算子数组的和&#xff0c;我们可以先构造前缀和数组 a&#xff0c;其中 a[i] 表示从第 1 个元素到第 i 个元素的…

家政服务小程序,家政行业数字化发展下的优势

今年以来&#xff0c;家政市场需求持续增长&#xff0c;市场规模达到了万亿级别&#xff0c;家政服务行业成为了热门行业之一&#xff01; 家政服务种类目前逐渐呈现了多样化&#xff0c;月嫂、保姆、做饭保洁、收纳、维修等家政种类不断出现&#xff0c;满足了居民日益增长的…

蓝桥杯每日真题 - 第12天

题目&#xff1a;&#xff08;数三角&#xff09; 题目描述&#xff08;14届 C&C B组E题&#xff09; 解题思路&#xff1a; 给定 n 个点的坐标&#xff0c;计算其中可以组成 等腰三角形 的三点组合数量。 核心条件&#xff1a;等腰三角形的定义是三角形的三条边中至少有…

Linux系统下svn新建目录

Linux安装svn自行查找 新建目录 新建一个自定义库的文件夹&#xff1a;mkdir security 使用svnadmin命令在新创建的目录中创建一个新的SVN版本库。例如&#xff1a; svnadmin create security 执行完成以上命令就会生成默认配置文件 通过pwd命令查找当前目录路径 路径&…