如何将视频流数据转换为cv :: gpumat?

时间:2018-11-07 07:10:22

标签: c++ video-streaming opencv3.0

我需要将视频流数据转换为cv :: gpumat。最初,我尝试复制到cv :: Mat,然后使用上载将其加载到gpumat。此过程非常慢(640 * 480帧为20ms)。

我需要一种将openni视频流直接转换为gpumat的方法。我尝试了以下代码,但它给出了运行时错误

我正在Ubuntu 16.04上使用opencv3.1,cuda-8.0,gtx titanx

#include "opencv2/opencv_modules.hpp"
#include <opencv2/core.hpp>
#include <opencv2/cudacodec.hpp>
#include <opencv2/highgui.hpp>

int main(int argc, const char* argv[])
{
    const std::string fname = argv[1];

    cv::cuda::GpuMat d_frame;
    cv::Ptr<cv::cudacodec::VideoReader> d_reader = cv::cudacodec::createVideoReader(fname);

    for (;;)
    {
        if (!d_reader->nextFrame(d_frame))
            break;

        cv::Mat frame;
        d_frame.download(frame);
        cv::imshow("GPU", frame);

        if (cv::waitKey(3) > 0)
            break;
    }
    return 0;
}

OpenCV Error: The function/feature is not implemented (The called functionality is disabled for current build or platform) in throw_no_cuda, file /home/krr/softwares/opencv-3.1.0/modules/core/include/opencv2/core/private.cuda.hpp, line 101
terminate called after throwing an instance of 'cv::Exception'
  what():  /home/krr/softwares/opencv-3.1.0/modules/core/include/opencv2/core/private.cuda.hpp:101: error: (-213) The called functionality is disabled for current build or platform in function throw_no_cuda

1 个答案:

答案 0 :(得分:1)

看看source code。该框架称为“ throw_no_cuda()”(不同之处,版本?)。同样,该错误似乎是github上this one的重复。

  

alalek:
  https://developer.nvidia.com/nvidia-video-codec-sdk

     
    

注意:对于Video Codec SDK 7.0和更高版本,NVCUVID已重命名为NVDECODE API。

  
     

OpenCV不支持新的API,也没有计划添加它。   带有NVCUVID的最新CUDA版本为CUDA 6.5。

     

考虑将ffmpeg与启用的CUDA功能一起使用(通过普通的cv :: VideoCapture-但不能与CUDA的cv :: GpuMat一起使用)。

进一步:

  

dapicard:
  我找到了一种定义FFMpeg后端使用的编解码器的方法:

     
    

export OPENCV_FFMPEG_CAPTURE_OPTIONS =“ video_codec | h264_cuvid”

  
     

更一般而言,可以使用语法parameter_name | value; parameter_name2 | value2来定义这些参数

也就是说,使用硬件功能解码视频(您尝试过)。旁注:ffmpeg还提供了直接在gpu上对视频进行转码的选项(即,无需远离gpu内存)。
坦白说,使用建议的方法不会导致矩阵直接传递到您的gpu内存,而只能解决错误。我认为无法直接从ffmpeg抓取内存,因此您无法移动它。