yolov5+bytetrack算法在华为NPU上进行端到端开发

        自从毕业后开始进入了华为曻腾生态圈,现在越来越多的公司开始走国产化路线了,现在国内做AI芯片的厂商比如:寒武纪、地平线等,虽然我了解的不多,但是相对于瑞芯微这样的AI开发板来说,华为曻腾的生态比瑞芯微好太多了,参考文档非常多,学习资料也有很多,也容易上手开发。

华为曻腾官网:昇腾AI应用案例-昇腾社区 (hiascend.com)

        直接步入正题,现在的目标检测已经很成熟了,所以越来越多的公司会用到基于检测的跟踪算法,这样不仅起到了单一检测功能,还有跟踪目标或者计数的功能;

        现在应用较广泛的目标检测算法从最开始的yolov5一直到现在的yolov8,虽然只是简单的看了一下算法的原理,整体来说yolo的更新还是针对神经网络在GPU上的优化加速,而对比曻腾NPU,yolov5的速度还是在其他yolo算法中速度最快的一个;

        目标跟踪算法以前是sort+yolo,deepsort+yolo,bytetrack,fairmot等算法,本章主要介绍如何利用华为的ACL语言+ffmpeg推流进行整个业务的开发流程,大家可以借鉴下面的开发代码,首先你要具备基本的ACL语言知识,以及yolov5的后处理逻辑,跟踪方面直接借鉴开源作者的卡尔曼滤波进行预测更新即可:参考主函数代码如下:

//1.先测试yolov5_nms可以泡桐?
//使用dvpp+aipp编解码再使用opencv进行#include<iostream>#include"acl/acl.h"
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/types_c.h"
#include "acllite/AclLiteUtils.h"
#include "acllite/AclLiteError.h"
#include "acllite/AclLiteResource.h"
#include "acllite/AclLiteModel.h"
#include "acllite/AclLiteImageProc.h"
#include "AclLiteVideoProc.h"
#include "AclLiteVideoCapBase.h"
#include "BYTETracker.h"
#include <chrono>
extern"C" {#include <libavutil/mathematics.h>#include <libavutil/time.h>#include "libavcodec/avcodec.h"#include "libavformat/avformat.h"#include "libswscale/swscale.h"#include "libavutil/imgutils.h"#include "libavutil/opt.h"
};
using namespace std;
using namespace cv;
typedef struct box {float x;float y;float w;float h;float score;size_t classIndex;size_t index; // index of output buffer
} box;
namespace{int a  = 0;
}
int main()
{//1.定义初始化变量dvpp\model\acl\rtsp解码接口capAclLiteResource aclDev;aclrtRunMode g_runMode_;AclLiteVideoProc* cap_;AclLiteImageProc g_dvpp_;AclLiteModel g_model_;string streamName_;streamName_ = "rtsp://admin:ascend666@10.1.16.108/LiveMedia/ch1/Media1";//ffmpeg初始化AVFormatContext* g_fmtCtx;AVCodecContext* g_codecCtx;AVStream* g_avStream;AVCodec* g_codec;AVPacket* g_pkt;AVFrame* g_yuvFrame;uint8_t* g_yuvBuf;AVFrame* g_rgbFrame;uint8_t* g_brgBuf;int g_yuvSize;int g_rgbSize;struct SwsContext* g_imgCtx;
//参数初始化
//rtsp初始化g_avStream = NULL;g_codec = NULL;g_codecCtx = NULL;g_fmtCtx = NULL;g_pkt  = NULL;g_imgCtx = NULL;g_yuvSize = 0;g_rgbSize = 0;int picWidth = 416;int picHeight = 416;string rtsp_url = "rtsp://192.168.3.38:8554/stream";int channelId = 0;string g_outFile = rtsp_url + to_string(channelId);
//rtsp初始化avformat_network_init();if (avformat_alloc_output_context2(&g_fmtCtx, NULL, g_avFormat.c_str(), g_outFile.c_str()) < 0) {ACLLITE_LOG_ERROR("Cannot alloc output file context");return ACLLITE_ERROR;}av_opt_set(g_fmtCtx->priv_data, "rtsp_transport", "tcp", 0);av_opt_set(g_fmtCtx->priv_data, "tune", "zerolatency", 0);av_opt_set(g_fmtCtx->priv_data, "preset", "superfast", 0);//获取编码器的ID返回一个编码器g_codec = avcodec_find_encoder(AV_CODEC_ID_H264);if (g_codec == NULL) {ACLLITE_LOG_ERROR("Cannot find any endcoder");return ACLLITE_ERROR;}g_codecCtx = avcodec_alloc_context3(g_codec);if (g_codecCtx == NULL) {ACLLITE_LOG_ERROR("Cannot alloc context");return ACLLITE_ERROR;}//创建流g_avStream = avformat_new_stream(g_fmtCtx, g_codec);if (g_avStream == NULL) {ACLLITE_LOG_ERROR("failed create new video stream");return ACLLITE_ERROR;}//设置帧率g_avStream->time_base = AVRational{1, g_frameRate};//设置编码参数AVCodecParameters* param = g_fmtCtx->streams[g_avStream->index]->codecpar;param->codec_type = AVMEDIA_TYPE_VIDEO;param->width = picWidth;param->height = picHeight;avcodec_parameters_to_context(g_codecCtx, param);//参数绑定设置g_codecCtx->pix_fmt = AV_PIX_FMT_NV12;g_codecCtx->time_base = AVRational{1, g_frameRate};g_codecCtx->bit_rate = g_bitRate;g_codecCtx->gop_size = g_gopSize;g_codecCtx->max_b_frames = 0;if (g_codecCtx->codec_id == AV_CODEC_ID_H264) {g_codecCtx->qmin = 10;g_codecCtx->qmax = 51;g_codecCtx->qcompress = (float)0.6;}if (g_codecCtx->codec_id == AV_CODEC_ID_MPEG1VIDEO)g_codecCtx->mb_decision = 2;//初始化codeif (avcodec_open2(g_codecCtx, g_codec, NULL) < 0) {ACLLITE_LOG_ERROR("Open encoder failed");return ACLLITE_ERROR;}//g_codecCtx参数传递给codecparavcodec_parameters_from_context(g_avStream->codecpar, g_codecCtx);//指定输出数据的形式av_dump_format(g_fmtCtx, 0, g_outFile.c_str(), 1);//写文件头int ret1 = avformat_write_header(g_fmtCtx, NULL);if (ret1 != AVSTREAM_INIT_IN_WRITE_HEADER) {ACLLITE_LOG_ERROR("Write file header fail");return ACLLITE_ERROR;}g_pkt = av_packet_alloc();//传输数据初始化g_rgbFrame = av_frame_alloc();g_yuvFrame = av_frame_alloc();g_rgbFrame->width = g_codecCtx->width;g_yuvFrame->width = g_codecCtx->width;g_rgbFrame->height = g_codecCtx->height;g_yuvFrame->height = g_codecCtx->height;g_rgbFrame->format = AV_PIX_FMT_BGR24;g_yuvFrame->format = g_codecCtx->pix_fmt;g_rgbSize = av_image_get_buffer_size(AV_PIX_FMT_BGR24, g_codecCtx->width, g_codecCtx->height, 1);g_yuvSize = av_image_get_buffer_size(g_codecCtx->pix_fmt, g_codecCtx->width, g_codecCtx->height, 1);g_brgBuf = (uint8_t*)av_malloc(g_rgbSize);g_yuvBuf = (uint8_t*)av_malloc(g_yuvSize);//内存分配int ret2 = av_image_fill_arrays(g_rgbFrame->data, g_rgbFrame->linesize,g_brgBuf, AV_PIX_FMT_BGR24,g_codecCtx->width, g_codecCtx->height, 1);ret2 = av_image_fill_arrays(g_yuvFrame->data, g_yuvFrame->linesize,g_yuvBuf, g_codecCtx->pix_fmt,g_codecCtx->width, g_codecCtx->height, 1);g_imgCtx = sws_getContext(g_codecCtx->width, g_codecCtx->height, AV_PIX_FMT_BGR24,g_codecCtx->width, g_codecCtx->height, g_codecCtx->pix_fmt,SWS_BILINEAR, NULL, NULL, NULL);//2.类变量初始化AclLiteError ret = aclDev.Init();if (ret) {ACLLITE_LOG_ERROR("Init resource failed, error %d", ret);return ACLLITE_ERROR;}if (ACLLITE_OK != OpenVideoCapture()) {return ACLLITE_ERROR;}ret = g_dvpp_.Init();if (ret) {ACLLITE_LOG_ERROR("Dvpp init failed, error %d", ret);return ACLLITE_ERROR;}cap_ = nullptr;ret = g_model_.Init();if (ret) {ACLLITE_LOG_ERROR("Model init failed, error %d", ret);return ACLLITE_ERROR;}//3.创建模型img_info的输入以及数据拷贝操作g_runMode_ = g_aclDev_.GetRunMode();const float imageInfo[4] = {(float)g_modelInputWidth, (float)g_modelInputHeight,(float)g_modelInputWidth, (float)g_modelInputHeight};g_imageInfoSize_ = sizeof(imageInfo);g_imageInfoBuf_ = CopyDataToDevice((void *)imageInfo, g_imageInfoSize_,g_runMode_, MEMORY_DEVICE);if (g_imageInfoBuf_ == nullptr) {ACLLITE_LOG_ERROR("Copy image info to device failed");return ACLLITE_ERROR;}//4.获取视频源cap_ = new AclLiteVideoProc(streamName_);//5.视频流解码以及dvpp硬件-resizeint i =0;while(true){//6.获取解码图片(在device侧的YUV420图片)(存放在ImageDta结构体中)
//         struct ImageData {
//     acldvppPixelFormat format;
//     uint32_t width = 0;
//     uint32_t height = 0;
//     uint32_t alignWidth = 0;
//     uint32_t alignHeight = 0;
//     uint32_t size = 0;
//     std::shared_ptr<uint8_t> data = nullptr;
// };
i++;ImageData image;ret = cap_->Read(image);ImageData resizedImage;ret = g_dvpp_.Resize(resizedImage, image, 640, 640);//7.创建模型输入进行模型推理ret = g_model_.CreateInput(resizedImage.data.get(), resizedImage.size,g_imageInfoBuf_, g_imageInfoSize_);if (ret != ACLLITE_OK) {ACLLITE_LOG_ERROR("Create mode input dataset failed, error:%d", ret);return ACLLITE_ERROR;}std::vector<InferenceOutput> inferenceOutput;ret = g_model_.Execute(inferenceOutput);if (ret != ACLLITE_OK) {g_model_.DestroyInput();ACLLITE_LOG_ERROR("Execute model inference failed, error: %d", ret);return ACLLITE_ERROR;}g_model_.DestroyInput();//8.将YUV图像转换为opencv图像ImageData yuvImage;ret = CopyImageToLocal(yuvImage, image, g_runMode_);if (ret == ACLLITE_ERROR) {ACLLITE_LOG_ERROR("Copy image to host failed");return ACLLITE_ERROR;}cv::Mat yuvimg(yuvImage.height * 3 / 2, yuvImage.width, CV_8UC1, yuvImage.data.get());cv::Mat origImage;cv::cvtColor(yuvimg, origImage, CV_YUV2BGR_NV12);//模型后处理(根据目标跟踪需要的输入进行获取xywh)float* detectData = (float *)inferenceOutput[0].data.get();float* boxNum = (float *)inferenceOutput[1].data.get();uint32_t totalBox = boxNum[0];//获取(x,y,w,h) std::vector<Object> obj;float widthScale = (float)(origImage.cols) / 640.0;float heightScale = (float)(origImage.rows) / 640.0;vector<box> detectResults;for (uint32_t i = 0; i < totalBox; i++) {box boundBox;boundBox.score = float(detectData[totalBox * SCORE + i]);boundBox.x = detectData[totalBox * TOPLEFTX + i] * widthScale;boundBox.y = detectData[totalBox * TOPLEFTY + i] * heightScale;boundBox.w = detectData[totalBox * BOTTOMRIGHTX + i] * widthScale;boundBox.h = detectData[totalBox * BOTTOMRIGHTY + i] * heightScale;boundBox.classIndex = (uint32_t)detectData[totalBox * LABEL + i];detectResults.emplace_back(boundBox);}for (size_t i = 0; i < detectResults.size(); i++){if (res[i].classId != class_id){ continue; }obj[i].label = detectResults[i].classIndex;obj[i].rect.x = detectResults[i].x;obj[i].rect.y = detectResults[i].y;obj[i].rect.height = detectResults[i].h;obj[i].rect.width = detectResults[i].w;obj[i].prob = detectResults[i].score;}std::vector<STrack> output_stracks = tracker.update(obj);for (size_t i = 0; i < output_stracks.size(); i++){std::vector<float> tlwh = output_stracks[i].tlwh;cv::Scalar __color = tracker.get_color(output_stracks[i].track_id);cv::putText(origImage, std::to_string(output_stracks[i].track_id), cv::Point(tlwh[0], tlwh[1] - 10), cv::FONT_ITALIC, 0.75, __color, 2);cv::rectangle(origImage, cv::Rect(tlwh[0], tlwh[1], tlwh[2], tlwh[3]), __color, 2);    }//跟踪完成后写推流memcpy(g_brgBuf, origImage.data, g_rgbSize);sws_scale(g_imgCtx,g_rgbFrame->data,g_rgbFrame->linesize,0,g_codecCtx->height,g_yuvFrame->data,g_yuvFrame->linesize);g_yuvFrame->pts = i;if (avcodec_send_frame(g_codecCtx, g_yuvFrame) >= 0) {// cout<<a<<endl;while (avcodec_receive_packet(g_codecCtx, g_pkt) >= 0) {cout<<"avcodec_receive_packet"<<endl;g_pkt->stream_index = g_avStream->index;av_packet_rescale_ts(g_pkt, g_codecCtx->time_base, g_avStream->time_base);g_pkt->pos = -1;int ret = av_interleaved_write_frame(g_fmtCtx, g_pkt);if (ret < 0) {ACLLITE_LOG_ERROR("error is: %d", ret);}}}}av_packet_free(&g_pkt);avcodec_close(g_codecCtx);if (g_fmtCtx) {avio_close(g_fmtCtx->pb);avformat_free_context(g_fmtCtx);}if (cap_ != nullptr) {cout << "cap is not open" << endl;cap_->Close();delete cap_;}dvpp_.DestroyResource();return 0;
}

跟踪器方面的函数,可以搜索开源代码yolov5-bytetrack-main.cpp截取内部跟踪部分,检测部分使用华为ACL编写的推理代码进行检测;

可以加入学习讨论:1076799627

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

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

相关文章

Python读取zip文件并解压,循环解压文件内的每个文件

读取并解压zip文件需要用到工具zipfile 示例代码 import zipfile import osdef readfile(path):files os.listdir(path)file_list []for file in files: # 遍历文件夹if not os.path.isdir(file):file_list.append(path / file)return file_listdef read_zip(file_name)…

麻省理工学院与Meta AI共同开发StreamingLLM框架,实现语言模型无限处理长度

&#x1f989; AI新闻 &#x1f680; 麻省理工学院与Meta AI共同开发StreamingLLM框架&#xff0c;实现语言模型无限处理长度 摘要&#xff1a;麻省理工学院与Meta AI的研究人员联合研发了一款名为StreamingLLM的框架&#xff0c;解决了大语言模型在RAM与泛化问题上的挑战&am…

SpringBoot如何动态更新yml文件?

前言 在系统运行过程中&#xff0c;可能由于一些配置项的简单变动需要重新打包启停项目&#xff0c;这对于在运行中的项目会造成数据丢失&#xff0c;客户操作无响应等情况发生&#xff0c;针对这类情况对开发框架进行升级提供yml文件实时修改更新功能 项目依赖 项目基于的是…

JAVA练习百题之求矩阵对角线之和

题目&#xff1a;求一个3*3矩阵对角线元素之和 程序分析 求一个3x3矩阵的对角线元素之和&#xff0c;我们需要将矩阵的左上到右下以及左下到右上两条对角线上的元素相加。 一个3x3矩阵如下所示&#xff1a; 1 2 3 4 5 6 7 8 9左上到右下的对角线元素和为1 5 9 15&…

信息系统项目管理师第四版学习笔记——配置与变更管理

配置管理 管理基础 配置管理是为了系统地控制配置变更&#xff0c;在信息系统项目的整个生命周期中维持配置的完整性和可跟踪性&#xff0c;而标识信息系统建设在不同时间点上配置的学科。 配置项的版本号规则与配置项的状态定义相关。例如&#xff1a;①处于“草稿”状态的…

CSPM考试报名条件是什么?好考吗?

★CSPM是什么&#xff1f; CSPM——项目管理专业人员能力评价&#xff0c;是中国人自己的一套项目管理专业人士的评价指南&#xff0c;符合中国国情且符合中国未来发展的一套项目刊专业人员能力评价的标准。 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff…

微信开发工具构建npm and git切换分支

目录 git切换分支NPM构建 git切换分支 案例&#xff1a; 再次查看分支就会发现自己的分支已切换&#xff0c;然后需要重新构建NPM一次 NPM构建 记得安装一下这个&#xff0c;然后在构建 如果未安装NPM&#xff0c;这时候需要打开命令端&#xff0c;安装操作&#xff0c;操作…

ubuntu编写makefile编译c++程序

常见的编译工具 gcc/gvisual cclang 编译一个简单的程序 main.cpp #include <iostream>int main() {std::cout << "hello world" << std::endl;return 0; }gcc 编译 源文件&#xff08;.cpp&#xff09;编译生成目标文件&#xff08;.o&#xf…

GNOME 45 动态三层缓存补丁更新

导读GNOME 45 "Rīga" 上周已正式发布&#xff0c;此版本虽然有许多针对桌面环境的改进&#xff0c;但上游缺少的一个功能是 Canonical 主导的 Mutter 动态三层缓存。 动态三层缓存用于在需要时提升性能&#xff0c;并且已被证明有助于提高桌面渲染性能&#xff0c;…

element-plus el-cascader 级联组件清空所选数据方法

话不多说直接上代码 import {ref, Ref, reactive} from vue; const cascaderOrg:Ref ref<any>(null) //获取级联组件的ref ref名称即cascaderOrg cascaderOrg.value.cascaderPanelRef.clearCheckedNodes(); //清空所选数据借用官方文档展示该方法 相关细节描述及全…

0029__时钟分频原理 - 时钟分频原理详解

时钟分频原理 - 时钟分频原理详解-CSDN博客

写进简历的软件测试项目实战经验(包含电商、银行、app等)

前言&#xff1a; 今天给大家带来几个软件测试项目的实战总结及经验&#xff0c;适合想自学、转行或者面试的朋友&#xff0c;可以写进简历里的那种哦。 1、项目名称: 家电购 项目描述&#xff1a; “家电购”商城系统是基于 web 浏览器的电子商务系统&#xff0c;通过互联…

为什么MyBatis是Java数据库持久层的明智选择

在Java应用程序的开发中&#xff0c;选择合适的数据库持久层框架至关重要。一个明智的选择可以帮助开发人员更好地管理数据库交互、提高性能和简化开发工作。 &#xff08;一&#xff09;为什么要选MyBatis JDBCHibernate / JPAMyBatis简单直接ORM轻量动态SQL关联查询开发效率…

深度学习batch、batch_size、epoch、iteration以及小样本中episode、support set、query set关系

batch、batch_size、epoch、iteration关系&#xff1a; epoch&#xff1a;整个数据集 batch&#xff1a; 整个数据集分成多少小块进行训练 batch_size&#xff1a; 一次训练&#xff08;1 batch&#xff09;需要 batch_size个样本 iteration&#xff1a; 整个数据集需要用b…

Bootstrap-- 媒体特性

最大、最小宽度例子&#xff1a; 横屏与竖屏例子&#xff1a; 宽度比与像素比例子&#xff1a;

Xception:使用Tensorflow从头开始实现

一、说明 近年来&#xff0c;卷积神经网络已成为计算机视觉领域的主要算法&#xff0c;开发设计它们的方法一直是相当的关注。Inception模型似乎能够用更少的参数学习更丰富的表示。它们是如何工作的&#xff0c;以及它们与常规卷积有何不同&#xff1f;本文将用tensorflow实现…

【专题】矩形和正方形的最大面积

一.矩形的最大面积——单调栈 &#xff08;1&#xff09;例题 P4147 玉蟾宫 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) &#xff08;2&#xff09;讲解&#xff08;摘自题解&#xff09; 问题转化&#xff1a; n行m列土地&#xff0c;求最大矩形面积&#xff0c;我们把…

2014款玛莎拉蒂吉博力车驾驶人侧车窗玻璃无法升降

作者&#xff1a;建德宝悦汽车服务中心 方超 方超&#xff0c;从事汽车维修工作12年&#xff0c;现任建德宝悦汽车服务中心技术经理。 故障现象 一辆2014款玛莎拉蒂吉博力车&#xff0c;搭载3.0T发动机&#xff0c;累计行驶里程约为7.4万km。车主进店反映&#xff0c;驾驶人侧…

论文学习记录--零样本学习(zero-shot learning)

Socher R, Ganjoo M, Manning C D, et al. Zero-shot learning through cross-modal transfer[J]. Advances in neural information processing systems, 2013, 26. 注&#xff1a;中文为机翻 zero-shot learning&#xff1a;通过学习类别之间的关系和属性&#xff0c;使得模型…

JUC并发编程:Monitor和对象结构

JUC并发编程&#xff1a;Monitor和对象结构 1. Monitor1.1 对象的结构1.1.1 MarkWord1.1.2 Klass Word1.1.3 数组长度1.1.4 &#x1f330; 1. Monitor Monitor官方文档 我们可以把Monitor理解为一个同步工具&#xff0c;也可以认为是一种同步机制。它通常被描述为一个对象&…