SURF_CUDA 计算描述符和关键点时出错

SURF_CUDA error while computing descriptors and keypoints

我正在 Oxford dataset(5000k 图像)上计算 SURF 描述符,依次调用以下方法:

void SURF_CUDAOpenCV::ComputeDescriptors(cv::Mat &img, cv::Mat1f &descriptors){
    cv::cuda::GpuMat imgGpu;
    std::vector<float> f_descriptors;
    std::vector<cv::KeyPoint> keypoints;
    imgGpu.upload(img);
    if(imgGpu.empty())
        throw std::runtime_error("Error uploading gpuImg");
    surf_cuda(imgGpu, cv::cuda::GpuMat(), keypoints, f_descriptors);
    descriptors = cv::Mat1f((int) f_descriptors.size()/surf_cuda.descriptorSize(), surf_cuda.descriptorSize(), f_descriptors[0]);
}

它成功地计算了部分图像的描述符(我在 surf_cuda(...) 之后打印了描述符的行和列)但它突然停止并出现此错误:

OpenCV Error: Assertion failed (layer_rows - 2 * min_margin > 0) in SURF_CUDA_Invoker, file /home/luca/ParallelOpenCV/opencv_contrib/modules/xfeatures2d/src/surf.cuda.cpp, line 134
error: /home/luca/ParallelOpenCV/opencv_contrib/modules/xfeatures2d/src/surf.cuda.cpp:134: error: (-215) layer_rows - 2 * min_margin > 0 in function SURF_CUDA_Invoker

为什么会这样?

我注意到一件奇怪的事情: 就行而言,出现错误的图像是在那一刻之前看到的最小图像。通常至少有 200 多行(但通常有 300、400 行),但在这种情况下有 "only" 117 行。也许这是问题所在?我记得使用经典 cv::xfeatures::SURF 它为一张非常小的图像检测到 0 个关键点,这就是为什么我认为这可能是问题所在。

发生错误是因为代码检查了图像的大小,而 Surf 无法正常处理小图像。

实际上在文件 opencv/opencv_contrib/modules/xfeatures2d/src/surf.cuda.cpp 中,构造函数 SURF_CUDA_Invoker 有几个与此错误中显示的断言类似的断言。

为什么 Surf 有这个问题?因为,这是一个设计约束。基本上处理小图像意味着使用更小的描述符导致没有足够的信息。

如果您想更进一步,可以查看此 other question 或一些有关冲浪的文档。