cv mat的shape_linux + opencv + cuvid中使用cv::cuda::GpuMat类的一些坑

1.我最终成功实现了opencv中利用cuvid实现GPU视频解码:

核心代码是:

1 cv::cuda::GpuMat d_frame;2 cv::Ptr<: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 classCV_EXPORTS_W GpuMat2 {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 is8 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, this15 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 is18 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 introws, 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

cudaGetDeviceCount(&num_devices);

cudaSetDevice(cuda_device);

//调用各种函数来初始化cuda运行环境,否则一执行就崩溃

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值