首页 > 解决方案 > opencv光流算法多线程实现没有加速

问题描述

我正在建立一个实时视频拼接项目,使用opencv光流算法。我面临的问题是光流计算需要很多时间,我试图在多个线程中使用它但它没有一点也不加快。我的代码有什么问题吗,或者有没有任何光流算法可以替代 opencv 提供的算法?提前致谢。这是我的测试代码:

Ptr<cuda::DensePyrLKOpticalFlow> brox[6];


void callOptical(GpuMat d_frame0f, GpuMat d_frame1f, GpuMat d_flow, Stream stream,int i)
{
    brox[i]->calc(d_frame0f, d_frame1f, d_flow, stream);
    brox[i]->calc(d_frame1f, d_frame0f, d_flow, stream);
}


int main()
{
    String filename[12] = { "l0.png", "r0.png", "l1.png", "r1.png", "l2.png", "r2.png", "l3.png", "r3.png", "l4.png", "r4.png", "l5.png", "r5.png" };
    Mat frame[12];
    GpuMat d_frame[12];
    GpuMat d_framef[12];
    for (int i = 0; i < 6; i++)
    {
        frame[2 * i] = imread(filename[2 * i], IMREAD_GRAYSCALE);
        frame[2 * i + 1] = imread(filename[2 * i + 1], IMREAD_GRAYSCALE);
        d_frame[2 * i].upload(frame[2 * i]);
        d_frame[2 * i + 1].upload(frame[2 * i + 1]);
        brox[i] = cuda::DensePyrLKOpticalFlow::create(Size(7, 7));
    }
    GpuMat d_flow[6];
    GpuMat pre_flow[6];
    Stream stream[6];


    vector<std::thread> threads;

    const int64 start = getTickCount();

    for (int i = 0; i < 6; i++)
    {
        threads.emplace_back(
            callOptical,
            d_frame[2 * i],
            d_frame[2 * i + 1],
            d_flow[i],
            stream[i],
            i
            );
    }

    for (std::thread& t : threads)
        t.join();

    const double timeSec = (getTickCount() - start) / getTickFrequency();
    cout << "Brox : " << timeSec << " sec" << endl;
    system("pause");
    return 0;
}

标签: c++multithreadingopencvopticalflow

解决方案


您的代码不是并行的 - t.join()!!!您需要调用 t.detach() 并等待所有线程都没有停止。

编辑:测试序列:

void callOptical(GpuMat d_frame0f, GpuMat d_frame1f, GpuMat d_flow, Stream stream,int i)
{
    std::cout << i << " begin..." <<  std::endl;
    brox[i]->calc(d_frame0f, d_frame1f, d_flow, stream);
    brox[i]->calc(d_frame1f, d_frame0f, d_flow, stream);
    std::cout << i << " end!" <<  std::endl;
}

编辑:使用openmp!

#pragma omp parallel for
for (int i = 0; i < 6; i++)
{
    callOptical(d_frame[2 * i], d_frame[2 * i + 1], d_flow[i], stream[i], i);
}

推荐阅读