当前位置: 首页 > news >正文

opencv rtsp 硬件解码

讨论使用opencv的reader

硬件解码的方案有太多种,如果使用ffmpeg硬件解码是最方便的,不方便的是把解码过后的GPU 拉到 CPU 上,再使用opencv的Mat 从cpu 上上载到gpu上,是不是多了两个过程,应该是直接从GPU mat 直接去处理, 最后一步再从GPU mat 上下载到cpu,render显示。

GPU 硬件解码是nv12 格式,我们为了显示和cpu使用直接转成了RGB或者BGR, 使用opencv再映射封装,最后又上载到cuda,这个过程很耗时间,而且不是必要的。

windows下使用cuda

经过实验,cv::cudacodec::createVideoReader 是可以拉取rtsp 流的,官方编译的可以读取rtsp,但是在文件流上出了问题,而且还有一个bug,就是在显示的时候,必须关闭一次窗口,才能显示后续的帧,而且还有一点,就是注意这个窗口必须是opengl 窗口,而且要打开这个窗口,而且在编译支持cuda的opencv时必须把opengl 勾选上,所以达不到产品化的要求,以下是测试代码:

#include <iostream>#include "opencv2/opencv_modules.hpp"#if defined(HAVE_OPENCV_CUDACODEC)#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/core/opengl.hpp>
#include <opencv2/cudacodec.hpp>
#include <opencv2/highgui.hpp>#if _DEBUG
#pragma comment(lib,"opencv_world460.lib")
#else 
#pragma comment(lib,"opencv_world460.lib")
#endif
int main()
{cv::cuda::printCudaDeviceInfo(cv::cuda::getDevice());int count = cv::cuda::getCudaEnabledDeviceCount();printf("GPU Device Count : %d \n", count);const std::string fname("rtsp://127.0.0.1/101-640.mkv"); //视频文件// const std::string fname("test_222.mp4"); //视频文件// cv::namedWindow("CPU", cv::WINDOW_NORMAL);cv::namedWindow("GPU", cv::WINDOW_OPENGL);cv::cuda::setGlDevice();cv::Mat frame;cv::VideoCapture reader(fname);cv::cuda::GpuMat d_frame;cv::Ptr<cv::cudacodec::VideoReader> d_reader = cv::cudacodec::createVideoReader(fname);cv::TickMeter tm;std::vector<double> cpu_times;std::vector<double> gpu_times;int gpu_frame_count = 0, cpu_frame_count = 0;
#if 0for (;;){tm.reset(); tm.start();if (!reader.read(frame))break;tm.stop();cpu_times.push_back(tm.getTimeMilli());cpu_frame_count++;cv::imshow("CPU", frame);if (cv::waitKey(1) > 0)break;}
#endiffor (;;){tm.reset();tm.start();if (!d_reader->nextFrame(d_frame))break;tm.stop();//d_frame.step = d_frame.cols * d_frame.channels();//cv::cuda::GpuMat gpuMat_Temp = d_frame.clone();gpu_times.push_back(tm.getTimeMilli());gpu_frame_count++;if (gpu_frame_count > 2){cv::Mat test;d_frame.download(test);d_frame.release();// cv::cvtColor(test, test, cv::COLOR_BGRA2BGR);//cv::imwrite("./test1.jpg", test);cv::imshow("GPU", test);}if (cv::waitKey(1) > 0)break;}if (!cpu_times.empty() && !gpu_times.empty()){std::cout << std::endl << "Results:" << std::endl;std::sort(cpu_times.begin(), cpu_times.end());std::sort(gpu_times.begin(), gpu_times.end());double cpu_avg = std::accumulate(cpu_times.begin(), cpu_times.end(), 0.0) / cpu_times.size();double gpu_avg = std::accumulate(gpu_times.begin(), gpu_times.end(), 0.0) / gpu_times.size();std::cout << "CPU : Avg : " << cpu_avg << " ms FPS : " << 1000.0 / cpu_avg << " Frames " << cpu_frame_count << std::endl;std::cout << "GPU : Avg : " << gpu_avg << " ms FPS : " << 1000.0 / gpu_avg << " Frames " << gpu_frame_count << std::endl;}return 0;
}

经过release版本的测试,cuda硬件解码比cpu慢很多,我cpu是intel 13代 13700,速度很快,gpu是3060ti, 实际测试就是如此。
说明在windows下实际类里面解码的时候在cpu和gpu上转换的时间太多
在这里插入图片描述
    综上所述,必须使用更为简单的方法,放弃windows上的做法,放到linux上, ffmpeg硬件解码 然后映射到gpu mat上,至于解码ffmpeg 可以看我的其他文章,至于ffmpeg 编解码 nvidia 上官网也是有介绍的:
编译ffmpeg
    使用python和linux,使用python的作用是取消c++ 到python之间的内存共享,在windows上编译pynvcodec 会遇到各种问题,建议在linux 编译 pynvcodec,为什么不使用ffmpeg直接解码,因为:我们使用ffmpeg解码得到的YUV格式,我们只能在CPU下转化到RGB的色彩空间,缺少在GPU上进行全部转化的流程,因此我们使用vpf 来进行python上的视频处理,同时结束时可以直接转化成pytorch的张量来处理。

    VideoProcessingFramework(VPF)是NVIDIA开源的适用于Python的视频处理框架,可用于硬件加速条件下的视频编解码等处理类任务。同时对于Pytorch比较友好,能够将解析出来的图像数据直接转化成Tensor()的格式。以下为例子:

import PyNvCodec as nvc
import PytorchNvCodec as pnvc  while True:# Read data.# Amount doesn't really matter, will be updated later on during decode.bits = proc.stdout.read(read_size)if not len(bits):print("Can't read data from pipe")breakelse:rt += len(bits)# Decodeenc_packet = np.frombuffer(buffer=bits, dtype=np.uint8)pkt_data = nvc.PacketData()try:surf = nvdec.DecodeSurfaceFromPacket(enc_packet, pkt_data)    # 获取流的数据# Convert to planar RGBrgb_pln = to_rgb.run(surf)   # 转换到rgb_plnif rgb_pln.Empty():break# PROCESS YOUR TENSOR HERE.# THIS DUMMY PROCESSING JUST ADDS RANDOM ROTATION.src_tensor = surface_to_tensor(rgb_pln)  # 转化为Tensor(),数据存储在GPU中dst_tensor = T.RandomRotation(degrees=(-1, 1))(src_tensor)surface_rgb = tensor_to_surface(dst_tensor, gpu_id)# Convert back to NV12dst_surface = to_nv12.run(surface_rgb) # 再转换回码流if src_surface.Empty():break# Handle HW exceptions in simplest possible way by decoder respawnexcept nvc.HwResetException:nvdec = nvc.PyNvDecoder(w, h, f, c, g)continue

使用gstreamer

近来来opencv的下载是一个问题,动不动就下载出错,使用gstreamer 在windows下和ffmpeg 差不离,编译也比较麻烦,我们尽量在linux下编译

sudo apt-get update 
sudo apt-get install build-essential cmake git pkg-config 
sudo apt-get install libjpeg8-dev libtiff4-dev libjasper-dev libpng12-dev 
sudo apt-get install libgtk2.0-dev 
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev 
sudo apt-get install libatlas-base-dev gfortran 
//在opencv里面安装gstreamer插件 
sudo apt-get install gstreamer1.0-tools gstreamer1.0-alsa gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav 
sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-good1.0-dev libgstreamer-plugins-bad1.0-dev cd /home/opencv 
git clone https://github.com/opencv.git 
cd opencv 
git checkout 4.7.0 
cd /home/opcv 
nkdir build 
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D CUDA_GENERATION=Kepler .. 
make -j4 
sudo make install
int main()
{// std::cout << cv::getBuildInformation() << std::endl;using std::chrono::steady_clock;typedef std::chrono::milliseconds milliseconds_type;const int interval = 15;std::stringstream ss;std::string rtsp_url = "rtsp://127.0.0.1/101-640.mkv";size_t latency = 200;size_t frame_width = 1920;size_t frame_height = 1080;size_t framerate = 15;ss << "rtspsrc location=" << rtsp_url << " latency=" << latency << " ! application/x-rtp, media=video, encoding-name=H264 "<< "! rtph264depay ! video/x-h264, clock-rate=90000, width=" << frame_width << ", height=" << frame_height << ", framerate="<< framerate << "/1 ! nvv4l2decoder ! video/x-raw(memory:NVMM), width=" << frame_width << ", height=" << frame_height<< ", framerate=" << framerate << "/1 ! nvvideoconvert ! video/x-raw, format=BGRx ! videoconvert ! video/x-raw, format=BGR ! appsink";std::cout << ss.str() << std::endl;cv::VideoCapture cap = cv::VideoCapture(ss.str(), cv::CAP_GSTREAMER);if (!cap.isOpened()){std::cerr << "error to open camera." << std::endl;return -1;}std::cout << cv::getBuildInformation() << std::endl;cv::Mat frame;steady_clock::time_point start = steady_clock::now();size_t frame_idx = 0;while (1){bool ret = cap.read(frame);if (ret){// cv::imwrite("tmp.jpg", frame);++frame_idx;}if (frame_idx % interval == 0){steady_clock::time_point end = steady_clock::now();milliseconds_type span = std::chrono::duration_cast<milliseconds_type>(end - start);std::cout << "it took " << span.count() / frame_idx << " millisencods." << std::endl;start = end;}}return 0;
}

一点一点排除,在windows上很难复现很多代码,很多都是不稳当的做法,只能做做demo,完全产品化不了,我们目前稳定的做法,1 是使用live555 ,下拉 rtsp,ffmpeg 硬件解码,转成mat,转成gpumat,再转成mat。这个方案不断修改吧。等我更新。

相关文章:

opencv rtsp 硬件解码

讨论使用opencv的reader 硬件解码的方案有太多种&#xff0c;如果使用ffmpeg硬件解码是最方便的&#xff0c;不方便的是把解码过后的GPU 拉到 CPU 上&#xff0c;再使用opencv的Mat 从cpu 上上载到gpu上&#xff0c;是不是多了两个过程&#xff0c;应该是直接从GPU mat 直接去…...

机器学习-Gradient Descent

机器学习(Gradient Descent) videopptblog 梯度下降(Gradient Descent) optimization problem: 损失函数最小化 假设本模型有两个参数&#x1d703;1和&#x1d703;2&#xff0c;随机取得初始值 求解偏微分&#xff0c;梯度下降对参数进行更新 Visualize: 确定梯度方向&…...

MySql003——SQL(结构化查询语言)基础知识

一、数据库的相关概念 DB&#xff1a;数据库&#xff08;Database&#xff09; 即存储数据的“仓库”&#xff0c;其本质是一个文件系统。它保存了一系列有组织的数据。DBMS&#xff1a;数据库管理系统&#xff08;Database Management System&#xff09; 是一种操纵和管理数…...

springCloud Eureka注册中心配置详解

1、创建一个springBoot项目 2、在springBoot项目中添加SpringCloud依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>2021.0.3</version><type>…...

gti 远程操作

目录 一. 分布式版本控制管理系统 1. 理解分布式版本控制管理系统 二. 创建远程仓库 ​编辑 ​编辑 三. 克隆远程仓库_HTTP 四. 克隆远程仓库_SSH 配置公钥 添加公钥 五. git 向远程仓库推送 六. 拉取远程仓库 七. 忽略特殊文件 八. 配置别名 一. 分布式版本控制管理…...

Ftrace

一、概述 Ftrace有剖析器和跟踪器。剖析器提供统计摘要&#xff0c;如激素胡和直方图&#xff1b;而跟踪器提供每一个事件的细节。 Ftrace剖析器列表&#xff1a; 剖析器描述function内核函数统计分析kprobe profiler启用的kprobe计数器uprobe profiler启用的uprobe计数器hi…...

Tomcat修改端口号

网上的教程都比较老&#xff0c;今天用tomcat9.0记录一下 conf文件夹下server.xml文件 刚开始改了打红叉的地方&#xff0c;发现没用&#xff0c;改了上面那行...

vue2企业级项目(一)

vue2企业级项目&#xff08;一&#xff09; 创建项目&#xff0c;并创建项目编译规范 1、node 版本 由于是vue2项目&#xff0c;所以 node 版本比较低。使用 12.18.3 左右即可 2、安装vue 安装指定版本的vue2 npm i -g vue2.7.10 npm i -g vue/cli4.4.63、编辑器规范 vsc…...

【前端知识】React 基础巩固(三十八)——log、thunk、applyMiddleware中间件的核心代码

React 基础巩固(三十八)——log、thunk、applyMiddleware中间件的核心代码 一、打印日志-中间件核心代码 利用Monkey Patching&#xff0c;修改原有的程序逻辑&#xff0c;在调用dispatch的过程中&#xff0c;通过dispatchAndLog实现日志打印功能 // 打印日志-中间件核心代码…...

hive删除数据进行恢复

在实际开发或生产中&#xff0c;hive表如果被误删&#xff0c;如被truncate或是分区表的分区被误删了&#xff0c;只要在回收站的清空周期内&#xff0c;是可以恢复数据的&#xff0c;步骤如下&#xff1a; &#xff08;1&#xff09; 先找到被删除数据的存放目录&#xff0c;…...

二、前端高德地图、渲染标记(Marker)引入自定义icon,手动设置zoom

要实现这个效果&#xff0c;我们先看一下目前的页面展示&#xff1a; 左边有一个图例&#xff0c;我们可以方法缩小地图&#xff0c;右边是动态的marker标记&#xff0c;到时候肯定时候是后端将对应的颜色标识、文字展示、坐标点给咱们返回、我们肯定可以拿到一个list&#xf…...

UDF和UDAF、UDTF的区别

UDF UDF&#xff08;User-defined functions&#xff09;用户自定义函数&#xff0c;简单说就是输入一行输出一行的自定义算子。 是大多数 SQL 环境的关键特性&#xff0c;用于扩展系统的内置功能。&#xff08;一对一&#xff09; UDAF UDAF&#xff08;User Defined Aggregat…...

小研究 - 浅析 JVM 中 GC 回收算法与垃圾收集器

本文主要介绍了JVM虚拟机中非常重要的两个部分&#xff0c;GC 回收算法和垃圾收集器。从可回收对象的标记开始&#xff0c;详细介绍 了四个主流的GC算法&#xff0c;详细总结了各自的算法思路及优缺点&#xff0c; 提出了何种情况下应该通常选用哪种算法。 目录 1 标记可回收对…...

Flowable-服务-骆驼任务

目录 定义图形标记XML内容Flowable与Camel集成使用示例设计Came路由代码 定义 Camel 任务不是 BPMN 2.0 规范定义的官方任务&#xff0c;在 Flowable 中&#xff0c;Camel 任务是作为一种特殊的服务 任务来实现的。主要做路由工作的。 图形标记 由于 Camel 任务不是 BPMN 2.…...

用html+javascript打造公文一键排版系统9:主送机关排版

一、主送机关的规定 公文一般在标题和正文之间还有主送机关&#xff0c;相关规定为&#xff1a; 主送机关 编排于标题下空一行位置&#xff0c;居左顶格&#xff0c;回行时仍顶格&#xff0c;最后一个机关名称后标全角冒号。如主送机关名称过多导致公文首页不能显示正文时&…...

SpringBoot 集成 EasyExcel 3.x 优雅实现 Excel 导入导出

介绍 EasyExcel 是一个基于 Java 的、快速、简洁、解决大文件内存溢出的 Excel 处理工具。它能让你在不用考虑性能、内存的等因素的情况下&#xff0c;快速完成 Excel 的读、写等功能。 EasyExcel文档地址&#xff1a; https://easyexcel.opensource.alibaba.com/ 快速开始 …...

RT1052 的四定时器

文章目录 1 Quad Timer&#xff0c;简称&#xff1a;QTMR2 单个通道的框图3 QTMR配置3.1 QTMR1 时钟使能。3.2 初始化 QTMR1。3.2.1 QTMR_Init 3.3 设置 QTMR1 通道 0 的定时周期。3.3.1QTMR_SetTimerPeriod 3.4 使能 QTMR1 通道 0 的比较中断。3.4.1 QTMR_EnableInterrupts 3.…...

ViT-vision transformer

ViT-vision transformer 介绍 Transformer最早是在NLP领域提出的&#xff0c;受此启发&#xff0c;Google将其用于图像&#xff0c;并对分类流程作尽量少的修改。 起源&#xff1a;从机器翻译的角度来看&#xff0c;一个句子想要翻译好&#xff0c;必须考虑上下文的信息&…...

Election of the King 2023牛客暑期多校训练营4-F

登录—专业IT笔试面试备考平台_牛客网 题目大意&#xff1a;有一个n个数的数组a&#xff0c;有n-1轮操作&#xff0c;每轮由每个数选择一个和它的差最大的数&#xff0c;如果相同就选值更大的&#xff0c;被最多数组选择的数字被删去&#xff0c;有相同的也去掉数值更大的那个…...

Nacos的搭建及服务调用

文章目录 一、搭建Nacos服务1、Nacos2、安装Nacos3、Docker安装Nacos 二、OpenFeign和Dubbo远程调用Nacos的服务1、搭建SpringCloudAlibaba的开发环境1.1 构建微服务聚合父工程1.2 创建子模块cloud-provider-payment80011.3 创建子模块cloud-consumer-order80 2、远程服务调用O…...

uniapp小程序自定义loding,通过状态管理配置全局使用

一、在项目中创建loding组件 在uniapp的components文件夹下创建loding组件&#xff0c;如图&#xff1a; 示例代码&#xff1a; <template><view class"loginLoading"><image src"../../static/loading.gif" class"loading-img&q…...

leetcode 45. 跳跃游戏 II

2023.7.30 class Solution { public:int jump(vector<int>& nums) {int step 0;int cover 0;int largest 0;if(nums.size() 1) return step;for(int i0; i<nums.size(); i){cover max(cover , inums[i]); //最大覆盖范围if(cover > nums.size()-1) retur…...

力扣热门100题之矩阵置0【中等】

题目描述 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]] 示例 2&#xff…...

【机器学习】Classification using Logistic Regression

Classification using Logistic Regression 1. 分类问题2. 线性回归方法3. 逻辑函数&#xff08;sigmod&#xff09;4.逻辑回归5. 决策边界5.1 数据集5.2 数据绘图5.3 逻辑回归与决策边界的刷新5.4 绘制决策边界 导入所需的库 import numpy as np %matplotlib widget import m…...

全方位支持图文和音视频、100+增强功能,Facebook开源数据增强库AugLy

Facebook 近日开源了数据增强库 AugLy&#xff0c;包含四个子库&#xff0c;每个子库对应不同的模态&#xff0c;每个库遵循相同的接口。支持四种模态&#xff1a;文本、图像、音频和视频。 最近&#xff0c;Facebook 开源了一个新的 Python 库——AugLy&#xff0c;该库旨在帮…...

RxSwift 使用方式

背景 最近项目业务&#xff0c;所有模块已经支持Swift混编开发&#xff0c;正在逐步使用Swift 方式进行开发新业务&#xff0c;以及逐步替换老业务方式进行发展&#xff0c;所以使用一些较为成熟的Swift 的三方库&#xff0c;成为必要性&#xff0c;经过调研发现RxSwift 在使用…...

HTML5 Web Worker

HTML5 Web Worker是一种浏览器提供的JavaScript多线程解决方案&#xff0c;它允许在后台运行独立于页面主线程的脚本&#xff0c;从而避免阻塞页面的交互和渲染。Web Worker可以用于执行计算密集型任务、处理大量数据、实现并行计算等&#xff0c;从而提升前端应用的性能和响应…...

25.9 matlab里面的10中优化方法介绍—— 惩罚函数法求约束最优化问题(matlab程序)

1.简述 一、算法原理 1、问题引入 之前我们了解过的算法大部分都是无约束优化问题&#xff0c;其算法有&#xff1a;黄金分割法&#xff0c;牛顿法&#xff0c;拟牛顿法&#xff0c;共轭梯度法&#xff0c;单纯性法等。但在实际工程问题中&#xff0c;大多数优化问题都属于有约…...

django channels实战(websocket底层原理和案例)

1、websocket相关 1.1、轮询 1.2、长轮询 1.3、websocket 1.3.1、websocket原理 1.3.2、django框架 asgi.py在django项目同名app目录下 1.3.3、聊天室 django代码总结 小结 1.3.4、群聊&#xff08;一&#xff09; 前端代码 后端代码 1.3.5、群聊&#xff08;二&#xff09…...

学习使用axios,绑定动态数据

目录 axios特性 案例一&#xff1a;通过axios获取笑话 案例二&#xff1a;调用城市天气api接口数据实现天气查询案例 axios特性 支持 Promise API 拦截请求和响应&#xff08;可以在请求前及响应前做某些操作&#xff0c;例如&#xff0c;在请求前想要在这个请求头中加一些…...