linux + opencv + cuvid中使用cv::cuda::GpuMat类的一些坑
1.我最终成功实现了opencv中利用cuvid实现GPU视频解码:
核心代码是:
1 cv::cuda::GpuMat d_frame;
2 cv::Ptr<cv::cudacodec::VideoReader> d_reader = cv::cudacodec::createVideoReader(mp4_file_name);
3 for (;;)
4 {
5 if (!d_reader->nextFrame(d_frame)) //BRGA格式
6 break;
7 gpu_frame_count++;
8 cv::Mat frame2;
9 d_frame.download(frame2);
10 cv::imwrite("xxx.png", frame2);
11 }
2.GupMat类的参考地址是:
https://docs.opencv.org/master/d0/d60/classcv_1_1cuda_1_1GpuMat.html
源码在: opencv-master/modules/core/include/opencv2/core/cuda.hpp
GPUMat类的成员变量都是public的,就算没有提供访问的方法也没关系。
一些重要的成员变量和成员函数是:
1 class CV_EXPORTS_W GpuMat
2 {
3 public:
4
5 /** @brief Performs data download from GpuMat (Blocking call)
6
7 This function copies data from device memory to host memory. As being a blocking call, it is
8 guaranteed that the copy operation is finished when this function returns.
9 */
10 CV_WRAP void download(OutputArray dst) const;
11
12 /** @brief Performs data download from GpuMat (Non-Blocking call)
13
14 This function copies data from device memory to host memory. As being a non-blocking call, this
15 function may return even if the copy operation is not finished.
16
17 The copy operation may be overlapped with operations in other non-default streams if \p stream is
18 not the default stream and \p dst is HostMem allocated with HostMem::PAGE_LOCKED option.
19 */
20 CV_WRAP void download(OutputArray dst, Stream& stream) const;
21
22 //! the number of rows and columns
23 int rows, cols;
24
25 //! a distance between successive rows in bytes; includes the gap if any
26 CV_PROP size_t step;
27
28 //! pointer to the data
29 uchar* data;
30
31 //! helper fields used in locateROI and adjustROI
32 uchar* datastart;
33 const uchar* dataend;
34
35 };
data是GPU内存中,存储图像数据的指针
datastart的地址与data相同
dataend指向图像存储空间的结束位置。(很可惜,这里是错误的)
rows 是图片的高度
cols是图片的宽度
channels() 返回4, 说明每个像素是四个字节,格式是BGRA
step是图片每行的字节数。注意:这个值是按2的幂对齐的。我测试中使用的图片,宽度是480,每像素四字节的话,一行应该是1920; 而此处的step值是2048, 每行多出来32像素,这些像素的alpha通道值为0。
因此,虽然看起来dataend-datastart是GPU内存所占空间大小,但实际的所占空间是:step*rows
3. GpuMat类使用dowmload()方法后,Mat类会去掉多余的对齐的像素
具体怎么做到的呢?搜索了很久终于找到源码原来在:opencv-master/modules/core/src/cuda/gpu_mat.cu
download方法的源码是:
1 void cv::cuda::GpuMat::download(OutputArray _dst) const
2 {
3 CV_DbgAssert( !empty() );
4
5 _dst.create(size(), type());
6 Mat dst = _dst.getMat();
7
8 CV_CUDEV_SAFE_CALL( cudaMemcpy2D(dst.data, dst.step, data, step, cols * elemSize(), rows, cudaMemcpyDeviceToHost) );
9 }
直接这样拷贝也是可以的:
cudaMemcpy(host_data, d_frame.data, d_frame.rows * d_frame.step , cudaMemcpyDeviceToHost);
但要注意:
#include <cuda_runtime.h>
cudaGetDeviceCount(&num_devices);
cudaSetDevice(cuda_device);
//调用各种函数来初始化cuda运行环境,否则一执行就崩溃
linux + opencv + cuvid中使用cv::cuda::GpuMat类的一些坑的更多相关文章
- 【记录一个问题】linux+opencv+cuvid解码1080P视频,当使用CUDA核函数的时候,必然崩溃
崩溃的信息如下: 1 OpenCV(4.1.0-dev) Error: Gpu API call (invalid configuration argument) in videoDecPostPro ...
- 【记录一个问题】cv::cuda::BufferPool发生assert错误
cv::cuda::setBufferPoolUsage(true); const int width = 512; const int height = 848; const int channel ...
- 【小记录】cv::cuda::Stream中取出cudaStream_t并用于核函数的计算
以下是找到的代码 1 cv::cuda::Stream stream; 2 cudaStream_t s = cv::cuda::StreamAccessor::getStream(stream); ...
- 【记录一个问题】linux + opencv + gpu视频解码,好不容易编译通过,运行又coredump了
1.首先编译了opencv + cuda 编译选项中使用了以下关于cuvid库的内容: //"nvcuvid" libraryCUDA_nvcuvid_LIBRARY:FILE ...
- Opencv undefined reference to `cv::imread() Ubuntu编译
Ubuntu下编译一个C++文件,C++源程序中使用了opencv,opencv的安装没有问题,但是在编译的过程中出现如下错误: undefined reference to `cv::imread( ...
- OpenCV图像处理中的“机器学习"技术的使用
注意,本文中所指"机器学习"(ML)技术,特指SVM.随机森林等"传统"技术. 一.应用场景 相比较当下发展迅速的各路"端到端" ...
- 【视频解码性能对比】opencv + cuvid + gpu vs. ffmpeg + cpu
视频大小:1168856 字节画面尺寸:480*848帧数:275opencv + cuvid + tesla P4, 解码性能:1426.84 fps ffmpeg 4.0 API + [Intel ...
- 【记录一个问题】cv::cuda::dft()比cv::dft()慢很多
具体的profile调用图如下: 可以看见compute很快,但是构造函数很慢. nvidia官网看到几篇类似的帖子,但是没有讲明白怎么解决的: opencv上的参考文档:https://docs.o ...
- 基於tiny4412的Linux內核移植--- 中斷和GPIO學習(3)
作者 彭東林 pengdonglin137@163.com 平臺 tiny4412 ADK Linux-4.4.4 u-boot使用的U-Boot 2010.12,是友善自帶的,爲支持設備樹和uIma ...
随机推荐
- Shell之awk常用用法
- Elasticsearch删除所有数据
使用post请求 POST http://localhost:9200/索引/标签/_delete_by_query?pretty { "query": { "match ...
- Linux生成SSH密钥对
执行 ssh-keygen -t rsa -P "" -f "/root/.ssh/id_rsa" 进入 cd /root/.ssh目录 (这里的root 是因 ...
- Excel转Json升级版-Python
Excel转Json升级版 将excel文件夹中所有xslx文件全部转换json文件,存放在data文件夹中: excel中的格式,从序号为2的行开始,2行为key:1行可以自由写注释: 使用时用双击 ...
- 【LeetCode】637. Average of Levels in Binary Tree 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:DFS 方法二:BFS 日期 题目地址:ht ...
- 【剑指Offer】52. 两个链表的第一个公共节点 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 方法一:栈 方法二:HashSet 方法三:不使用额外空间 日期 ...
- Docker 与 K8S学习笔记(六)—— 容器的资源限制
我们在启动Docker容器时,默认情况下容器所使用的资源是没有限制的,这样就会存在部分特别耗资源的容器会占用大量系统资源,从而导致其他容器甚至整个服务器性能降低,为此,Docker提供了一系列参数方便 ...
- MCU变量加载过程
前言 在开发mcu代码的时候经常会有些疑惑,变量是怎么在编译之后进入单片机的ram区的呢,特别是在使用keil开发的时候.后来在接触gcc编译器和自研的mcu后,终于明白了这个问题.实际上变量编译后被 ...
- Spring Boot 2 中的默认日志管理与 Logback 配置详解
Spring Boot在所有内部日志中使用Commons Logging,但是对底层日志的实现是开放的.在Spring Boot生态中,为Java Util Logging .Log4J2 和Logb ...
- docker-部署jumpserver
jumpserver https://jumpserver.org/ Docker 部署 jumpserver 堡垒机 容器部署 jumpserver-1.4.10 服务端 #最好单一个节点 容器运行 ...