试图执行我的自定义函数的OpenCV CUDA错误-217

时间:2017-09-13 14:45:52

标签: opencv cuda

我试图将cv::cuda::FarnebackOpticalFlow算法的输出转换为3个无符号字节的YUV平面(以便通过FFMPEG进行后续压缩)。

我在调用stream.waitForCompletion()时收到错误代码-217("未指定的启动失败")(此处未显示);在我的内核中触发错误的是尝试为其中一个输出GpuMat对象赋值(请参阅dst_y(y, x) = ...下面的行)。

我在Windows 10下使用从源代码编译的OpenCV 3.3。

我使用CMake cuda_add_executable()命令来定义我的项目,并且我已经使用set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -arch compute_50 -code sm_50)定义了CUDA标记,尽管我已经尝试了不再有的变体成功。我的显卡是GTX 970。

#include <opencv2/core/cuda_stream_accessor.hpp>

using namespace cv;
using namespace cuda;


namespace 
{
    __global__ void kernelFunc(
        const PtrStepSz<float2>& src,
        float scale_x, float scale_y,
        PtrStepSzb dst_y, PtrStepSzb dst_u, PtrStepSzb dst_v)
    {
        int x = blockIdx.x * blockDim.x + threadIdx.x;
        int y = blockIdx.y * blockDim.y + threadIdx.y;

        if (x < src.cols && y < src.rows && y >= 0 && x >= 0)
        {
            // Get input: optical flow, and scale it
            auto dx = scale_x * src(y, x).x, dy = scale_y * src(y, x).y;

            // Luma: flow vector length, compressed using an exponential function
            auto l = sqrt(dx*dx + dy*dy);
            l = exp(5*l) / (exp(5*l) + 1);
            dst_y(y, x) = 255 * l;

            // Chroma (U and V)
            dst_u(y, x) = 255 * (dx + 0.5);
            dst_v(y, x) = 255 * (dy + 0.5);
        }
    }

} // ns

void compress_optical_flow_mat_to_yuv444(const GpuMat& src, 
    GpuMat& dst_y, GpuMat& dst_u, GpuMat& dst_v, 
    Stream& stream)
{
    using namespace std::string_literals;

    dst_y.create(src.size(), CV_8UC1); 
    dst_u.create(src.size(), CV_8UC1); 
    dst_v.create(src.size(), CV_8UC1); 

    dim3 cthreads(16, 16); //(32, 8);
    dim3 cblocks(
        static_cast<int>(ceil(src.size().width  / static_cast<double>(cthreads.x))),
        static_cast<int>(ceil(src.size().height / static_cast<double>(cthreads.y))));

    // We scale optical flow so that the range [-0.5..0.5] covers half the width and half the height,
    // in pixels, of the image. In other words, a given pixel may not move by more than half the
    // image size per frame.
    float scale_x = 0.5f / src.size().width;
    float scale_y = 0.5f / src.size().height;
    auto cu_str = StreamAccessor::getStream(stream);

    kernelFunc<<<cblocks, cthreads, 0, cu_str>>>(src, scale_x, scale_y, dst_y, dst_u, dst_v);

    auto err = cudaGetLastError();
    if (err != 0) 
        throw std::runtime_error("compress_optical_flow_mat_to_yuv444() kernel call failed with error "s 
            + std::to_string(err) + ": " + cudaGetErrorString(err));
}

1 个答案:

答案 0 :(得分:1)

从以下行中删除&符号:

__global__ void kernelFunc(
        const PtrStepSz<float2>& src,
        float scale_x, float scale_y,
        PtrStepSzb dst_y, PtrStepSzb dst_u, PtrStepSzb dst_v)

__global__ void kernelFunc(
        const PtrStepSz<float2> src,
        float scale_x, float scale_y,
        PtrStepSzb dst_y, PtrStepSzb dst_u, PtrStepSzb dst_v)