简体   繁体   English

Opencv 如何通过 GPU 读取网络摄像头 stream?

[英]Opencv how to read webcam stream via on GPU?

I can use VideoReader class of OpenCV to decode an IP camera stream or any video file by using its path.我可以使用OpenCV的 VideoReader class 通过使用其路径解码 IP 相机 stream 或任何视频文件。 This decoding process is using GPU as expected, no problem up to now.这个解码过程按预期使用了GPU,到现在没问题。 Here is simple code which is working fine and using GPU for decoding:这是工作正常并使用 GPU 进行解码的简单代码:

int main()
{
    const std::string fname("rtsp://user:pwd@192.168.1.108"); 
    // const std::string fname("/path/to/video/file.mp4"); // this also works    
    cv::cuda::GpuMat d_frame;
    cv::Ptr<cv::cudacodec::VideoReader> d_reader = cv::cudacodec::createVideoReader(fname);    
    Mat frame;        
    for (;;)
    {

        if (!d_reader->nextFrame(d_frame))
            break;    
        Mat myMat(d_frame);            
        cv::imshow("GPU", myMat);

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

    return 0;
}

I want to use GPU to capture streams from my webcam as like VideoCapture(0) .我想使用 GPU 从我的网络摄像头捕获流,就像VideoCapture(0)一样。 I know as @berak mentioned here : There is no way to do that with VideoCapture我知道 @berak 在这里提到:没有办法用VideoCapture做到这一点

My questions are:我的问题是:

1 - Is it possible to stream by using GPU with VideoReader class? 1 - 是否可以通过将 GPU 与 VideoReader class 一起使用来实现 stream? Because VideoReader class only accepts strings not indexes.因为 VideoReader class 只接受字符串而不接受索引。

2- What are the other ways to be able to stream by using GPU? 2- 使用 GPU 可以通过哪些其他方式连接到 stream?

1) Yes, it seems so! 1)是的,似乎是这样! I found the following code in the openCV GPU samples here .我在这里的 openCV GPU 示例中找到了以下代码。 You could give it a try.你可以试一试。 You need to have OpenCV built with OpenGL though... Currently that's where I'm stuck.不过,您需要使用 OpenGL 构建 OpenCV ... 目前这就是我遇到的问题。

2) I'm not sure about other options, but here is the code from the Github. 2)我不确定其他选项,但这是来自 Github 的代码。

#include <iostream>

#include "opencv2/opencv_modules.hpp"

#if defined(HAVE_OPENCV_CUDACODEC)

#include <string>
#include <vector>
#include <algorithm>
#include <numeric>

#include <opencv2/core.hpp>
#include <opencv2/core/opengl.hpp>
#include <opencv2/cudacodec.hpp>
#include <opencv2/highgui.hpp>

int main(int argc, const char* argv[])
{
    std::cout << "Starting,...\n";
    const std::string fname = "0";
    
    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;

    for (;;)
    {
        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(3) > 0)
            break;
    }

    for (;;)
    {
        tm.reset(); tm.start();
        if (!d_reader->nextFrame(d_frame))
            break;
        tm.stop();
        gpu_times.push_back(tm.getTimeMilli());
        gpu_frame_count++;

        cv::imshow("GPU", d_frame);

        if (cv::waitKey(3) > 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;
}

#else

int main()
{
    std::cout << "OpenCV was built without CUDA Video decoding support\n" << std::endl;
    return 0;
}

#endif

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM