pycharm + anaconda + yolo11(ultralytics) 的视频流实时检测,保存推流简单实现

目录

  • 背景
  • pycharm安装配置
  • 代码实现
    • 创建本地视频配置 和 推流配置
    • 视频帧的处理和检测框绘制
    • 主要流程
    • 遇到的一些问题

背景

首先这个基于完整安装配置了anaconda和yolo11的环境,如果需要配置开始的话,先看下专栏里另一个文章。
这次的目的是实现拉取视频流,做检测并绘制对象检测框。之后,将结果保存本地视频,并且推流到对应的rtmp服务器,便于调试也可以实时显示处理结果视频。

pycharm安装配置

安装就不提了吧,到官网下载个免费的社区版本就ok了,安装也基本不会有啥问题。
安装完成后,打开你的本地ultralytics文件夹作为项目,然后在设置里加一下解释器:
在这里插入图片描述
记得选对你的anaconda配置的环境,右边的列表能看到你环境中安装的库。

代码实现

创建本地视频配置 和 推流配置

依据传入的opencv捕获的视频流对象,获取本地保存视频的一些参数,创建video_writer,并记录推流参数。

def create_video_writer(cap_video, path_output):# 获取视频流参数width = int(cap_video.get(cv2.CAP_PROP_FRAME_WIDTH))height = int(cap_video.get(cv2.CAP_PROP_FRAME_HEIGHT))fps = int(cap_video.get(cv2.CAP_PROP_FPS))# 初始化本地视频保存fourcc = cv2.VideoWriter.fourcc(*'mp4v')out_writer = cv2.VideoWriter(path_output, fourcc, fps, (width, height))# 推流的参数配置command = ['ffmpeg','-y',                    # 覆盖输出文件(如果存在)'-f', 'rawvideo',        # 输入格式'-pix_fmt', 'bgr24',     # OpenCV 的像素格式'-s', f'{width}x{height}', # 分辨率'-r', str(fps),          # 帧率'-i', '-',               # 从标准输入读取'-c:v', 'libx264',       # 输出视频编码'-preset', 'ultrafast',       # 编码速度预设'-f', 'flv',             # 输出格式(RTMP 需要 flv)RTMP_SERVER_URL]print("视频参数:fps " + str(fps))return out_writer, command

视频帧的处理和检测框绘制

依据传入的模型对象和视频帧,去绘制检测框和文本,之后返回结果的图像以及结果数据。

def process_frame(model_in, frame_in):results = model_in.predict(frame_in)# 绘制检测框for result in results:for box in result.boxes:x1, y1, x2, y2 = map(int, box.xyxy[0])conf = box.conf[0].item()cls_id = int(box.cls[0])label = f"{model_in.names[cls_id]} {conf:.2f}"print(label)# 绘制矩形和标签draw_rounded_rect(frame_in, (x1, y1), (x2, y2), (0, 255, 0), 2,cv2.LINE_AA, 10)  # 红色圆角矩形cv2.putText(frame_in, label, (x1, y1 - 10),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)return frame_in, results

draw_rounded_rect 单纯为了绘制个圆角框,可以简单的用cv2.rectangle(frame_in, (x1, y1), (x2, y2), (0, 255, 0), 2, cv2.LINE_AA)画。

def draw_rounded_rect(img, pt1, pt2, color, thickness, line_type, corner_radius):x1, y1 = pt1x2, y2 = pt2# 绘制四个角的圆弧cv2.ellipse(img, (x1 + corner_radius, y1 + corner_radius), (corner_radius, corner_radius), 180, 0, 90, color, thickness, line_type)cv2.ellipse(img, (x2 - corner_radius, y1 + corner_radius), (corner_radius, corner_radius), 270, 0, 90, color, thickness, line_type)cv2.ellipse(img, (x1 + corner_radius, y2 - corner_radius), (corner_radius, corner_radius), 90, 0, 90, color, thickness, line_type)cv2.ellipse(img, (x2 - corner_radius, y2 - corner_radius), (corner_radius, corner_radius), 0, 0, 90, color, thickness, line_type)# 绘制四条边cv2.line(img, (x1 + corner_radius, y1), (x2 - corner_radius, y1), color, thickness, line_type)cv2.line(img, (x1, y1 + corner_radius), (x1, y2 - corner_radius), color, thickness, line_type)cv2.line(img, (x1 + corner_radius, y2), (x2 - corner_radius, y2), color, thickness, line_type)cv2.line(img, (x2, y1 + corner_radius), (x2, y2 - corner_radius), color, thickness, line_type)

主要流程

流程主要就是加载模型,捕获对应的rtmp视频流,跑循环一帧帧解析数据,之后把帧的绘制结果写入本地的视频文件,同时帧结果也通过ffmpeg库推到对应的RTMP server去播放。最后终端清除资源。

# 加载模型
model = YOLO(MODEL_PATH)
# 初始化视频流
cap = cv2.VideoCapture(RTSP_URL)
if not cap.isOpened():raise ValueError("无法打开视频流!")
print("视频流已连接...")
out_writer, ffmpeg_command = create_video_writer(cap, OUTPUT_VIDEO_PATH)
if ENABLE_FEATURE_STREAM:# 启动 FFmpeg 进程ffmpeg_proc = subprocess.Popen(ffmpeg_command, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
if ENABLE_FEATURE_DISPLAY:cv2.namedWindow("DISPLAY", cv2.WINDOW_NORMAL)
print("本地视频写入配置完成...")
try:while True:ret, frame = cap.read()if not ret:print("视频流中断,尝试重连...")cap.release()cap = cv2.VideoCapture(RTSP_URL)time.sleep(1)continue# 处理单帧画面out_frame, _ = process_frame(model, frame)if ENABLE_FEATURE_DISPLAY:frame_small = cv2.resize(out_frame, (1080, 900))cv2.waitKey(1)cv2.imshow("DISPLAY", frame_small)if ENABLE_FEATURE_STREAM:# 推流到服务器if ffmpeg_proc.stdin:ffmpeg_proc.stdin.write(out_frame.tobytes())# 保存到本地out_writer.write(out_frame)
except KeyboardInterrupt:print("用户中断操作")
finally:# 清理资源cap.release()out_writer.release()if ENABLE_FEATURE_STREAM:if ffmpeg_proc.stdin:ffmpeg_proc.stdin.close()ffmpeg_proc.terminate()print("等待进程退出")ffmpeg_proc.wait()print("资源已释放")

然后前面的import,就是缺什么装什么,直接在conda环境里pip装就好了。

from ultralytics import YOLO
import cv2
import time
import subprocess
import numpy as np# 参数
ENABLE_FEATURE_STREAM = True
ENABLE_FEATURE_DISPLAY = True
RTSP_URL = "rtmp://xxxxx"  # RTSP 或 HTTP 流地址
OUTPUT_VIDEO_PATH = "YOLO11OutPut.mp4"  # 本地保存路径
RTMP_SERVER_URL = "rtmp://xxxxxx"  # 推流服务器地址
MODEL_PATH = "yolo11n.pt"

效果就是跑起来前端会有实时视频,并且本地会有mp4保存,远端服务器也能实时看到视频。
在这里插入图片描述
至于什么效果啥的就是后续自己调整的事情了。

遇到的一些问题

  • 第一个是图里后续加了中文标签,默认opencv字体不支持绘制中文会是?问号。
    有两个方法一个是去改yolo的绘制代码,比较麻烦,我最后用的是转PIL绘制,当然需要下字体文件SimHei.ttf丢在目录下。标签的可以在项目内的ultralytics/ultralytics/blob/main/ultralytics/cfg/datasets/coco.yaml找到识别的标签集合,自己简单补个对应中文标签组。至于代码不难,就参考着自己调整吧:
from PIL import Image, ImageDraw, ImageFont
cn_names = {0: "人", 1: "自行车", 2: "汽车", 3: '摩托车', 4: '飞机', 5: '大巴', 6: '火车', 7: '卡车', 8: '船', 9: '信号灯'
}
font_path = "SimHei.ttf"
font_size = 20
font = ImageFont.truetype(font_path, font_size)
def put_text_cn(img, text, pos, color, font):# 转换 OpenCV 图像为 PIL 格式img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))draw = ImageDraw.Draw(img_pil)# 计算文本尺寸并绘制背景框bbox = draw.textbbox((0, 0), text, font=font)text_width = bbox[2] - bbox[0]  # 宽度 = 右边界 - 左边界text_height = bbox[3] - bbox[1]  # 高度 = 下边界 - 上边界x, y = posbg_pos = (x, y - text_height-5, x + text_width, y)# draw.rectangle(bg_pos, fill=color)# 绘制文本draw.text((bg_pos[0], bg_pos[1]), text, font=font, fill=(255, 255, 255))  # 白色文字# 转换回 OpenCV 格式return cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
  • 第二个是一开始跑yolo的时候遇到过报“NotImplementedError: Could not run 'torchvision::nms“错误。查了下是已安装库版本的问题,参考https://stackoverflow.com/questions/75103127/getting-notimplementederror-could-not-run-torchvisionnms-with-arguments-fr
    uninstall对应的torch库然后重新安装官网链接安装一次试试~
  • 还有就是如果下载模型异常,也是跑不起来的,网络实在不行可以考虑直接去yolo的文档里找预训练的模型链接,把模型下下来丢项目根目录先:
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LLM:了解大语言模型

大型语言模型(Large language models,LLMs),如 OpenAI 的 ChatGPT ,或者 DeepSeek 等,是过去几年中开发出来的深度神经网络模型。它们为自然语言处理(natural language processing,N…

Linux多进程学习

一、什么是多进程 1.多任务程序能够同时做多件事情,如QQ同时聊天和上传下载。 2.多任务程序在应用开发中非常普遍,是必须掌握的基本概念。 二、进程的创建与资源分配 1.操作系统在创建进程时会分配内存资源、CPU资源和时间片。 2.进程的内容包括代码、…

「Unity3D」UGUI将元素固定在,距离屏幕边缘的某个比例,以及保持元素自身比例

在不同分辨率的屏幕下,UI元素按照自身像素大小,会发生位置与比例的变化,本文仅利用锚点(Anchors)使用,来实现UI元素,固定在某个比例距离的屏幕边缘。 首先,将元素的锚点设置为中心&…

STM32 内置的通讯协议

数据是以帧为单位发的 USART和UART的区别就是有没有同步功能 同步是两端设备有时钟连接,异步是没时钟连接,靠约定号的频率(波特率)接收发送数据 RTS和CTS是用来给外界发送已“可接收”或“可发送”信号的,一般用不到…

C语言实现队列数据结构:思路与代码详解

目录 一、引言 二、整体思路 三、代码模块分析 (一)头文件包含与宏定义 (二)数据类型定义 (三)队列操作函数 1. 队列初始化 2. 队列销毁 3. 入队操作 4. 出队操作 5. 获取队头元素 6…

商业智能BI的未来,如何看待AI+BI这种模式?

昨天在和一位朋友线上聊天的时候,提了一个问题,你是如何看待AI(人工智能)BI(商业智能)这种模式和方向的,我大概来说一下我个人的看法。 以我在商业智能BI项目中接触到的行业和企业,…

如何制作Windows系统盘、启动盘?(MediaCreationTool_22H2)

文章目录 每日一句正能量前言一、准备工作二、制作启动盘后记 每日一句正能量 每个在你生命里出现的人,都有原因。喜欢你的人给你温暖关心。你喜欢的人让你学会爱和付出,不喜欢你的人让你自省成长。你不喜欢的人教会你宽容尊重,没有人是偶然出…

DataWhale 大语言模型 - 语言模型发展历程

大语言模型 LLMBook 项目背景 本课程围绕中国人民大学高瓴人工智能学院赵鑫教授团队出品的《大语言模型》书籍展开,覆盖大语言模型训练与使用的全流程,从预训练到微调与对齐,从使用技术到评测应用,帮助学员全面掌握大语言模型的…

C#带有设备仿真功能串口调试助手

本文档介绍一种方法,可以用来仿真串口设备。这样调试PLC程序时可以在没有仪器时用于测试程序的运行。详细代码见: https://download.csdn.net/download/qq_34047402/90477066 C#带有设备仿真功能串口调试助手资源-CSDN文库 步骤如下: 1.把串口设备接收和发送仿真数据放到一…

本地部署 OpenManus 保姆级教程(Windows 版)

一、环境搭建 我的电脑是Windows 10版本,其他的没尝试,如果大家系统和我的不一致,请自行判断,基本上没什么大的出入啊。 openManus的Git地址:https://github.com/mannaandpoem/OpenManus 根据官网的两种安装推荐方式如…

01 | Go 项目开发极速入门课介绍

提示: 所有体系课见专栏:Go 项目开发极速入门实战课。 你好,欢迎学习本课程。本课程是一个 Go 项目开发极速入门课程。旨在帮助刚学习完 Go 基础语法的 Go 开发者,快速掌握如何开发一个功能相对全面的 Go 项目。 根据课程设计目标…

使用 Elastic-Agent 或 Beats 将 Journald 中的 syslog 和 auth 日志导入 Elastic Stack

作者:来自 Elastic TiagoQueiroz 我们在 Elastic 一直努力将更多 Linux 发行版添加到我们的支持矩阵中,现在 Elastic-Agent 和 Beats 已正式支持 Debian 12! 本文演示了我们正在开发的功能,以支持使用 Journald 存储系统和身份验…

江科大51单片机笔记【15】直流电机驱动(PWM)

写在前言 此为博主自学江科大51单片机(B站)的笔记,方便后续重温知识 在后面的章节中,为了防止篇幅过长和易于查找,我把一个小节分成两部分来发,上章节主要是关于本节课的硬件介绍、电路图、原理图等理论…

【Linux】:封装线程

朋友们、伙计们,我们又见面了,本期来给大家带来封装线程相关的知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! C 语 言 专 栏:C语言:从入门到精通 数据结…

全球领先的光学方案设计公司:倚光科技

在光学技术革新的浪潮中,倚光(深圳)科技有限公司以创新者的姿态迅速崛起,成为全球光学领域的标杆企业。自 2021 年成立以来,公司始终聚焦纳米光学技术研发与超精密加工,凭借顶尖的技术实力和前瞻性的市场布…

2.2.3 TCP—UDP-QUIC

文章目录 2.2.3 TCP—UDP-QUIC1. TCP如何做到可靠性传输1. ACK机制2. 重传机制3. 序号机制4. 窗口机制5. 流量机制6. 带宽机制 2. tcp和udp如何选择1. tcp和udp格式对比2. ARQ协议(Automatic Repeat reQuest,自动重传请求)1. ARQ协议的主要类…

【动手实验】TCP 连接的建立与关闭抓包分析

本文是基于知识星球程序员踩坑案例分享中的作业进行的复现和总结,借此加深对 TCP 协议的理解, 原文参见TCP 连接的建立和关闭 —— 强烈建议新手看看。 实验环境 这里使用两台位于同一子网的腾讯云服务器,IP 分别是 node2(172.1…

视频理解之Actionclip(论文宏观解读)

配合解读代码解读 1.研究背景 1. 视频行为识别的重要性 视频行为识别是视频理解领域的核心任务之一,旨在通过分析视频内容来识别和分类其中的人物行为或活动。这一任务在多个领域具有重要的应用价值,例如智能监控、人机交互、自动驾驶、医疗健康等。随…

基于LabVIEW的脚本化子VI动态生成

该示例展示了一种利用LabVIEW VI脚本(VI Scripting)技术,通过程序化方式动态生成并替换子VI的解决方案。核心逻辑为:基于预定义的模板VI,根据用户选择的数学操作(加法或乘法),自动生…

Debian系统grub新增启动项

参考链接 给grub添加自定义启动项_linux grub定制 启动项名称自定义-CSDN博客 www.cnblogs.com 1. boot里面的grub.cfg 使用vim打开boot里面的grub.cfg sudo vim /boot/grub/grub.cfg 这时候会看到文件最上方的提示 2. 真正配置grub的文件 从刚才看到的文件提示中&#x…