海思3403对RTSP进行目标检测

news2024/11/16 0:07:53

1.概述

主要功能是调过live555 testRTSPClient 简单封装的rtsp客户端库,拉取RTSP流,然后调过3403的VDEC模块进行解码,送个NPU进行目标检测,输出到hdmi,这样保证了开发没有sensor的时候可以识别其它摄像头的视频流;

2.如何搭建一个RTSPServer

2.1使用live555 mediaServer搭建rtspServer
#这里可以去http://live555.com/官网查看
wget http://live555.com/liveMedia/public/live.2024.10.31.tar.gz
tar xvzf live.2024.10.31.tar.gz
cd live
./genMakefiles linux-no-std-lib
make -j
cd mediaServer
./live555MediaServer

执行的效果如下,默认支持的文件list如下,只需要把对应类型的文件复制到mediaServer目录即可,可以用vlc测试是否正常

LIVE555 Media Server
	version 1.13 (LIVE555 Streaming Media library version 2024.10.31).
Play streams from this server using the URL
	rtsp://192.168.8.8:8554/<filename>
where <filename> is a file present in the current directory.
Each file's type is inferred from its name suffix:
	".264" => a H.264 Video Elementary Stream file
	".265" => a H.265 Video Elementary Stream file
	".aac" => an AAC Audio (ADTS format) file
	".ac3" => an AC-3 Audio file
	".amr" => an AMR Audio file
	".dv" => a DV Video file
	".m4e" => a MPEG-4 Video Elementary Stream file
	".mkv" => a Matroska audio+video+(optional)subtitles file
	".mp3" => a MPEG-1 or 2 Audio file
	".mpg" => a MPEG-1 or 2 Program Stream (audio+video) file
	".ogg" or ".ogv" or ".opus" => an Ogg audio and/or video file
	".ts" => a MPEG Transport Stream file
		(a ".tsx" index file - if present - provides server 'trick play' support)
	".vob" => a VOB (MPEG-2 video with AC-3 audio) file
	".wav" => a WAV Audio file
	".webm" => a WebM audio(Vorbis)+video(VP8) file
See http://www.live555.com/mediaServer/ for additional documentation.
(We use port 8000 for optional RTSP-over-HTTP tunneling).)

2.2 ffmpeg转264文件

如果是mp4文件可以用ffmpeg简单的提取264文件,命令如下

#sudo apt-get install ffmpeg
ffmpeg -i input.mp4 -an -codec:v copy output.264

3.封装RtspClinet

代码参考live/testProgs/testRTSPClient.cpp
需要注意Nal头即可,不同RtspServer会有不同的发包方式

void DummySink::afterGettingFrame(unsigned frameSize,
                                  unsigned numTruncatedBytes,
                                  struct timeval presentationTime,
                                  unsigned /*durationInMicroseconds*/)
	{
	//frameSize 这个是一帧图像
	//  u_int8_t *fReceiveBuffer;这个是frame数据内容
	//struct timeval presentationTime,这个是当前frame的pts
	}

完整代码参考开源仓库下面目录

//thridpart/live555/librtspclient.h
RTSPCLI_API int MyRTSP_Init(RTSP_Handle** handle);/*句柄  返回0表示成功,返回非0表示失败 */
RTSPCLI_API int MyRTSP_Deinit(RTSP_Handle* handle);/* 释放RTSPClient 参数为RTSPClient句柄 */
RTSPCLI_API int MyRTSP_OpenStream(RTSP_Handle* handle, const char* _url, EASY_RTP_CONNECT_TYPE _connType,int _reconn/*1000表示长连接,即如果网络断开自动重连, 其它值为连接次数*/);/* 打开网络流 */
RTSPCLI_API int MyRTSP_SetCallback(RTSP_Handle* handle,RTSPSourceCallBack _callback, void* userptr);/* 设置数据回调 */
RTSPCLI_API int MyRTSP_Run(RTSP_Handle* handle);
RTSPCLI_API int MyRTSP_CloseStream(RTSP_Handle* handle);/* 关闭网络流 */

4.整合数据给VDEC

#include "librtspclient.h"
RTSP_Handle* hRTSPHandle_;
int RtspRunnig_ = 0;
pthread_t rtsp_thd_;
void *pRtspFrame = NULL;
static char sps[32];
static char pps[32];
static int spslen = 0;
static int ppslen = 0;
static int initvpss = 0;
static int RTSPSourceCall(EASY_FRAME_INFO_T frameinfo, void* userdata)
{
    // printf("frameinfo.framesize:%d,bIFrame:%d:NaluType:%d\n", frameinfo.framesize, frameinfo.bIFrame, frameinfo.NaluType);
    //这里做了简单是数据拼接,主要是为了给VDEC 完整的264帧,有问题可以调试下这部分数据,需要有nal头00 00 00 01 +xxx
    //I帧 nal+sps + nal+pps +nal +iframe
    //p帧 nal + pframe
    if (frameinfo.NaluType == 0x07)
    {
        memcpy(sps, frameinfo.framebuff, frameinfo.framesize);
        spslen = frameinfo.framesize;
        return 0;
    }
    else if (frameinfo.NaluType == 0x08)
    {
        memcpy(pps, frameinfo.framebuff, frameinfo.framesize);
        ppslen = frameinfo.framesize;
        return 0;
    }
    uint32_t len = 0;
    if (frameinfo.bIFrame)
    {
        memcpy(pRtspFrame, sps, spslen);
        len += spslen;
        memcpy(pRtspFrame + len, pps, ppslen);
        len += ppslen;
        memcpy(pRtspFrame + len, frameinfo.framebuff, frameinfo.framesize);
        len += frameinfo.framesize;
    }
    else
    {
        memcpy(pRtspFrame + len, frameinfo.framebuff, frameinfo.framesize);
        len += frameinfo.framesize;
    }

    ot_vdec_stream stream;
    ot_vdec_chn vdecchn = 0;
    td_s32 milli_sec = 40;
    ot_vpss_grp grp = 0;
    ss_mpi_sys_get_cur_pts(&stream.pts);
    stream.addr = pRtspFrame;
    stream.len = len;
    stream.end_of_frame = TD_TRUE;
    stream.end_of_stream = TD_FALSE;
    stream.need_display = TD_TRUE;

    ss_mpi_vdec_send_stream(vdecchn, &stream, -1);
    ot_video_frame_info frame_info;
    ot_vdec_supplement_info supplement;
    ss_mpi_vdec_get_frame(vdecchn, &frame_info, &supplement, milli_sec);
    if (initvpss == 0 && frame_info.video_frame.width > 0)
    {
    	//第一帧解析成功才创建vpss通道
        ot_size in_size;
        in_size.width = frame_info.video_frame.width;
        in_size.height = frame_info.video_frame.height;
        printf("vpss init W: H:%d\n", in_size.width, in_size.height);
        sample_vio_start_vpss(grp, &in_size);
        initvpss = 1;
    }
    ss_mpi_vpss_send_frame(grp, &frame_info, milli_sec);
    ss_mpi_vdec_release_frame(vdecchn, &frame_info);

    return 0;
}
void* RtspProcess(void* args) {
    while (RtspRunnig_) {
        MyRTSP_Run(hRTSPHandle_);
    }
    printf("Rtsp thread Finish\n");
    return NULL;
}
void RtspStart(const char* url)
{
    pRtspFrame = malloc(1024*1024);
    RtspRunnig_ = 1;
    MyRTSP_Init(&hRTSPHandle_);
    MyRTSP_SetCallback(hRTSPHandle_, RTSPSourceCall, NULL);
    MyRTSP_OpenStream(hRTSPHandle_, url, EASY_RTP_OVER_TCP, 0);
    pthread_create(&rtsp_thd_, 0, RtspProcess, NULL);
}
void RtspStop()
{
    RtspRunnig_ = 0;
    MyRTSP_Deinit(hRTSPHandle_);
    pthread_join(rtsp_thd_, NULL);
    free(pRtspFrame);
    pRtspFrame = NULL;
}

5.完整Demo

后端处理的pipleline参考,直接把vdec流送给vpss,后面npu的部分在以前yolov8_deepsort_mp4分支中查看即可
在这里插入图片描述

6.工程代码

6.1代码仓库地址

giee仓库地址

6.2下载编译代码
git clone -b yolov8_deepsort_rtsp --depth=1 --single-branch https://gitee.com/apchy_ll/ss928_yolov5s.git
cd ss928_yolov5s
./build.sh
cp -rf output ~/work/nfs/3403/
6.3板端运行
./rundemo.sh rtsp://192.168.8.8:8554/output.264 

7.教学视频

11 SS928 Yolov8检测RTSP流

8.谢谢

请多多支持!

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

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

相关文章

Python学习26天

集合 # 定义集合 num {1, 2, 3, 4, 5} print(f"num&#xff1a;{num}\nnum数据类型为&#xff1a;{type(num)}") # 求集合中元素个数 print(f"num中元素个数为&#xff1a;{len(num)}") # 增加集合中的元素 num.add(6) print(num) # {1,2,3,4,5,6} # 删除…

图论-代码随想录刷题记录[JAVA]

文章目录 前言深度优先搜索理论基础所有可达路径岛屿数量岛屿最大面积孤岛的总面积沉默孤岛Floyd 算法dijkstra&#xff08;朴素版&#xff09;最小生成树之primkruskal算法 前言 新手小白记录第一次刷代码随想录 1.自用 抽取精简的解题思路 方便复盘 2.代码尽量多加注释 3.记录…

测试自动化如何和业务流程结合?

测试自动化框架固然重要&#xff0c;但是最终自动化的目的都是为了业务服务的。 那测试自动化如何对业务流程产生积极影响&#xff1f; 业务流程的重要性 测试自动化项目并非孤立存在&#xff0c;其生命周期与被测试的应用程序紧密相关。项目的价值在于被整个开发团队所使用&a…

大模型基础BERT——Transformers的双向编码器表示

大模型基础BERT——Transformers的双向编码器表示 整体概况 BERT&#xff1a;用于语言理解的深度双向Transform的预训练 论文题目&#xff1a;BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding Bidirectional Encoder Representations from…

Leetcode 56-合并区间

以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 //按左边界排序 //startintervals[i][0],endintervals…

【golang-技巧】-线上死锁问题排查-by pprof

1.背景 由于目前项目使用 cgo golang 本地不能debug, 发生死锁问题&#xff0c;程序运行和期待不一致&#xff0c;通过日志排查可以大概率找到 阻塞范围&#xff0c;但是不能找到具体问题在哪里&#xff0c;同时服务器 通过k8s daemonset 部署没有更好的方式暴露端口 获取ppr…

7天用Go从零实现分布式缓存GeeCache(总结)

1. Lru包 1.1 lru算法简要概述 &#xff08;作者&#xff1a;豆豉辣椒炒腊肉/链接&#xff1a;https://juejin.cn/post/6844904049263771662&#xff09; LRU算法全称是最近最少使用算法&#xff08;Least Recently Use&#xff09;&#xff0c;广泛的应用于缓存机制中。当缓…

oracle查询字段类型长度等字段信息

1.查询oracle数据库的字符集 SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER NLS_CHARACTERSET; 2.查询字段长度类型 SELECT * FROM user_tab_columns WHERE table_name user AND COLUMN_NAME SNAME 请确保将user替换为您想要查询的表名。sname为字段名 这里的字…

前端面试笔试(一)

目录 一、数据结构算法等综合篇 1.直接插入排序&#xff0c;有n个元素待排序&#xff0c;则最多进行多少次比较 2.软件测试中评估网络性能的关键指标有哪些 3.哈希查找 4.内存保护 二、代码输出篇 1.promise中throw new Error输出 2.Promise.all 3.this关键字,obj.get…

iOS 18.2 重磅更新:6个大动作

根据外媒报道&#xff0c;iOS 18.2迎来重磅更新&#xff0c;将带来6个大动作&#xff0c;这是一次非常实用的更新。不过要注意的是&#xff0c;其中涉及到AI的功能&#xff0c;国行iPhone 暂时还不可用&#xff0c;只能等审核通过了。 1&#xff0c;Safari下载进度 过去通过S…

HBase理论_HBase架构组件介绍

近来有些空闲时间&#xff0c;正好最近也在开发HBase相关内容&#xff0c;借此整理一下学习和对HBase组件的架构的记录和个人感受&#xff0c;付出了老夫不少心血啊&#xff0c;主要介绍的就是HBase的架构设计以及我的拓展内容。内容如有不当或有其他理解 matirx70163.com HB…

【Spring AOP 原理】

首先AOP跟OOP(面向对象编程)、IOC(控制反转)一样都是一种编程思想 跟OOP不同, AOP是面向切面编程, 面对多个不具备继承关系的对象同时需要引入一段公共逻辑的时候, OOP就显得有点笨重了, 而AOP就游刃有余, 一个切面可以横跨多个类或者对象去执行公共逻辑, 极大的提升了开发效率…

第六节、Docker 方式部署指南 github 上项目 mkdocs-material

一、简介 MkDocs 可以同时编译多个 markdown 文件,形成书籍一样的文件。有多种主题供你选择,很适合项目使用。 MkDocs 是快速,简单和华丽的静态网站生成器,可以构建项目文档。文档源文件在 Markdown 编写,使用单个 YAML 配置文件配置。 MkDocs—markdown项目文档工具,…

论文 | The Capacity for Moral Self-Correction in LargeLanguage Models

概述 论文探讨了大规模语言模型是否具备“道德自我校正”的能力&#xff0c;即在收到相应指令时避免产生有害或偏见输出的能力。研究发现&#xff0c;当模型参数达到一定规模&#xff08;至少22B参数&#xff09;并经过人类反馈强化学习&#xff08;RLHF&#xff09;训练后&…

初识GIS

文章目录 一、什么叫地理信息1、定义2、主要特点3、分类 二、什么叫GIS1、定义2、GIS对空间信息的储存2.1、矢量数据模型2.2、栅格数据模型 3、离散栅格和连续栅格的区别 三、坐标系统1、为什么要存在坐标系统&#xff1f;2、地理坐标系2.1、定义与特点2.2、分类 3、投影坐标系…

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

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

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项目,…